gpt4 book ai didi

typescript - 预期有 3 个类型参数但得到 1 个但它应该推断出 2 种类型

转载 作者:搜寻专家 更新时间:2023-10-30 21:25:50 26 4
gpt4 key购买 nike

我想知道如何正确推断函数的第二个和第三个模板

假设一个简单的界面

interface ISome {
a: string;
b?: {
c: string;
};
}

关注作品

function pathBuilder<
K1 extends keyof ISome,
K2 extends keyof NonNullable<ISome[K1]>>(p: K1, p2?: K2) {
let res = String(p);
if (p2) { res += "." + p2; }
return res;
}

const pathTest = pathBuilder("b", "c"); // ---> "b.c" and intellisense works on parameters

但我需要通过指定另一种类型来概括函数以工作(我不想传递对象实例来指定类型)

所以,跟随是行不通的

function pathBuilder<
T,
K1 extends keyof T,
K2 extends keyof NonNullable<T[K1]>>(p: K1, p2?: K2) {
let res = String(p);
if (p2) { res += "." + p2; }
return res;
}

const pathTest = pathBuilder<ISome>("b", "c"); // ERROR: Expected 3 type arguments, but got 1.ts(2558)

似乎函数的第二个和第三个模板参数不是从第一个模板参数推断出来的,但它应该是因为在第一种情况下,当我直接指定类型 T=ISome 时它起作用了。

我不确定是否有一些语言关键字可以让它工作,但模板应该完全适合:指定一个未知类型。

编辑

实际上我是这样找到的,但需要额外的编码,我会尽可能避免

function pathBuilder<T>() {
return <
K1 extends keyof T,
K2 extends keyof NonNullable<T[K1]>>(p: K1, p2?: K2) => {
let res = String(p);
if (p2) { res += "." + p2; }
return res;
};
}

const pathTest = pathBuilder<ISome>()("b", "c");

最佳答案

从 TS3.4 开始,没有 partial type parameter inference .要么让编译器尝试推断所有类型参数,要么指定所有类型参数。 (好吧,有 default type parameters 但这并没有给你你想要的:你想推断你遗漏的类型参数,而不是分配一个默认类型给他们)。已有several建议address这个,但到目前为止none have met with full approval .

因此,目前只有解决方法。我能想到的两个是使用虚拟函数参数或使用 currying .

虚拟参数版本:

function pathBuilderDummy<
T,
K1 extends keyof T,
K2 extends keyof NonNullable<T[K1]>>(dummy: T, p: K1, p2?: K2) {
let res = String(p);
if (p2) { res += "." + p2; }
return res;
}

const pathDummyTest = pathBuilderDummy(null! as ISome, "b", "c");

这里我们正在做你说过你不想做的事情...传递一个T类型的参数。但由于它只是一个虚拟参数并且不在运行时使用,所以它只与类型系统认为它是什么有关。您传入的值的实际类型并不重要。所以你可以传递它 null 并使用 type assertion选择 T

柯里化(Currying)函数解决方案:

const pathBuilderCurry =
<T>() => <
K1 extends keyof T,
K2 extends keyof NonNullable<T[K1]>>(p: K1, p2?: K2) => {
let res = String(p);
if (p2) { res += "." + p2; }
return res;
}

const pathCurryTest = pathBuilderCurry<ISome>()("b", "c")

此处您返回一个函数,该函数返回另一个函数。第一个函数不接受任何值参数,但它接受您要指定的一个类型参数。然后它返回一个函数,其中指定了 T 但推断出其他类型参数。

这两种解决方案都不是完美的,但它们是我们目前能做的最好的。希望有所帮助;祝你好运!

关于typescript - 预期有 3 个类型参数但得到 1 个但它应该推断出 2 种类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55754822/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com