为什么不解析函数的参数类型,对象的哪个元素(typescript)?

时间:2018-02-05 19:11:14

标签: typescript

任何人都可以帮助我吗? 这是3个例子:a,b,c。对于第一和第二" arg" type为true(数字)。对于第三版本,打字稿不能解析" 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

1 个答案:

答案 0 :(得分:4)

当两个类型参数具有依赖关系并且需要依赖于另一个参数推断时,编译器会有点困惑。我使用的一个简单的工作是执行两步调用,第一个函数修复第一个参数类型,第二个调用可以推断出其余的类型:

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

修改

虽然上述解决方案可以正确推断T,但正如@MihailMalostanidis所建议的那样,在这种情况下可能根本不需要使用第二个参数。这也正确推断:

function c<K extends { [index: string]: number } >(
    arg1: K,
    arg2: {[P in keyof K]?: ((value: number) => string) },
)  {
    return null;
}

不同之处在于,如果您要从函数(或基于arg2的类型)返回T,则在此版本中K的所有键都将存在,而不仅仅是调用时arg2中实际指定的那些。根据您的使用情况,这可能是可以接受的,但初始解决方案适用于所有情况。