有人可以帮助我吗?这是3个示例:a,b,c。对于第一个和第二个" arg"类型为true(数字(。对于第三版TypeScript无法解析" arg"类型。
function a<T extends (value: number) => string>(
arg: T,
) {
return null;
}
a((arg) => arg.toExponential()); // ARG HAS RIGHT TYPE: number
function b<T extends { [index: string]: (value: number) => string }>(
arg: T,
) {
return null;
}
b({ x: (arg) => arg.toExponential() }); // ARG HAS RIGHT TYPE: number
function c<K extends { [index: string]: number }, T extends {[P in keyof K]?: ((value: number) => string) }>(
arg1: K,
arg2: T,
) {
return null;
}
c({ x: 15 }, { x: (arg) => arg.toExponential() }); // ARGS NOT HAS TYPE: any
当两个类型参数具有依赖关系并且需要推断一个依赖于另一个时,编译器会变得有些混乱。我使用的一个简单的工作是进行两个步骤调用,第一个函数修复了第一个参数类型,第二个呼叫可以将其余的类型推断为:
function c<K extends { [index: string]: number }>(arg1: K)
{
return function <T extends {[P in keyof K]?: ((value: number) => string) }>(arg2: T){
};
}
c({ x: 15 })({ x: (arg) => arg.toExponential() }); // arg will be number
编辑
尽管如@mihailmalostanidis所建议的,上面的解决方案可以正确地渗透T
,但在这种情况下,根本不需要使用第二个参数。这也正确地提出了:
function c<K extends { [index: string]: number } >(
arg1: K,
arg2: {[P in keyof K]?: ((value: number) => string) },
) {
return null;
}
区别在于,如果您要从函数(或基于T
的类型(返回arg2
,则在此版本中,K
的所有键都会存在,而不仅仅是在调用arg2
中实际指定的键。根据您的用例,这可能是可以接受的,但是初始解决方案在所有情况下都适用。