簡體   English   中英

條件類型中的TypeScript類型推斷

[英]TypeScript type inference in conditional types

我對以下示例中的類型推斷方式感到困惑

type RetType<T> = T extends (...args: (infer I)[]) => infer R ? [I, R] : any;
type X = (a: number, b: string) => void;
type Q = RetType<X>;

如果您將鼠標懸停在操場上的Q類型上,您將獲得[number & string, void] 這令人困惑,因為我希望I被推斷為number | string number | string (union)而不是number & string (intersection)。

有沒有人理解為什么輸入參數被推斷為交集而不是聯合?

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.

換句話說, f可賦值給g因為g的參數可賦值給f 這種逆轉是對立面

因此,如果T是一些神秘功能類型的子類型(...args: I[]) => R ,參數禁忌方差告訴我們, I必須是可分配給參數類型的T

因此, T extends (...args: (infer I)[]) => infer R告訴typescript推斷某些單一類型I這樣I就可以用來代替T任何參數。

所以對於你的類型X ,無論I是什么,它都應該是真的,它必須可以分配給兩個參數。 由於參數類型分別是numberstring ,我們會問: 兩種類型都可分配哪種類型?

好吧, number & string


*有關更多信息,您可能有興趣閱讀co和contra-variance

這可能不是您正在尋找的答案或解釋,但這在文檔中提到

同樣,反變量位置中相同類型變量的多個候選者會導致交叉類型被推斷:

 type Bar<T> = T extends { a: (x: infer U) => void, b: (x: infer U) => void } ? U : never; type T20 = Bar<{ a: (x: string) => void, b: (x: string) => void }>; // string type T21 = Bar<{ a: (x: string) => void, b: (x: number) => void }>; // string & number 

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM