Dav*_*yan 4 types type-inference typescript
在以下示例中,我对如何推断类型感到困惑
type RetType<T> = T extends (...args: (infer I)[]) => infer R ? [I, R] : any;
type X = (a: number, b: string) => void;
type Q = RetType<X>;
Run Code Online (Sandbox Code Playgroud)
如果将鼠标悬停Q
在操场上的类型上,您将得到[number & string, void]
。之所以令人困惑,是因为我希望I
将其推断为number | string
(联合)而不是number & string
(交集)。
有谁知道为什么将输入参数推断为交集而不是并集?
TL; DR:因为无论如何I
,它必须可分配给函数类型的所有参数T
。
这是因为函数参数是反变量的。这只是意味着要使用一个函数代替另一个函数,其参数类型必须与另一个函数相同或更通用。当您看一个示例时,这很明显:
type f: (arg: string) => string;
type g: (arg: "foo") => string;
// f is assignable to g, since a function expecting
// to receive any string should have no problem accepting
// the specific string "foo".
// However, the reverse isn't true. You can't assign g to f,
// since g expects to receive exactly the string "foo" for its
// argument, but if it's used in place of f, it can receive any string.
Run Code Online (Sandbox Code Playgroud)
换句话说,f
之所以可分配给,是g
因为g
的自变量可分配给f
的。逆转是相反的部分。
因此,如果T
是某个神秘函数类型的子类型(...args: I[]) => R
,则参数相反方差告诉我们I
必须将其分配给的参数类型T
。
因此,T extends (...args: (infer I)[]) => infer R
告诉typescript推断某种单一类型I
,以便I
可以代替的任何参数使用T
。
因此,对于您的type X
,无论I
是什么,它都必须可分配给两个参数,这是事实。由于参数类型分别为number
和string
,我们问:这两个参数都可以分配什么类型?
好吧,number & string
。
*有关更多信息,您可能对阅读协方差和逆方差感兴趣。
归档时间: |
|
查看次数: |
280 次 |
最近记录: |