簡體   English   中英

為什么 Typescript 映射元組類型在提供通用類型與直接類型時表現不同?

[英]Why are Typescript Mapped Tuple Types behaving differently when supplying Generic type vs direct type?

export type MyTuple = ["test", "othertest"];

type NotWorking = {
    [K in keyof MyTuple]: { value: MyTuple[K]};
};

type NotWorkingLengthType = NotWorking["length"]; // { value: 2 }

type Working<T>= {
    [P in keyof T]: { value: T[P] };
};

type MappedWorking = Working<MyTuple>;
type MappedWorkingLengthType = MappedWorking["length"]; // 2

為什么在這種情況下表現不同? 這讓我很困惑。

這實際上看起來像一個錯誤,請參閱microsoft/TypeScript#27995


通常{[K in keyof T]: ...T[K]...}形式的映射類型被認為是同態映射類型,並盡可能保留輸入類型T的結構。 這發生在可選和readonly鍵上(請參閱microsoft/TypeScript#12563 ),這也是在microsoft/TypeScript#26063中實現映射元組/數組時的意圖。

為了讓這工作,這意味着編譯器必須看[K in keyof T]並記得保持T有否評估后,各地keyof T T是泛型類型時會發生這種情況,對於可選/ readonly鍵,當T是某種具體類型時也會發生這種情況:

type MyObj = { a?: string, readonly b: number };
type MyMappedObj = { [K in keyof MyObj]: { value: MyObj[K] } }
/* type MyMappedObj = {
    a?: {
        value: string | undefined;
    } | undefined;
    readonly b: {
        value: number;
    };
} */

請注意,這個時候你的映射類型是明確遍歷與正好鍵“只適用in keyof ”。 如果您以其他方式計算您的鍵,或將它們分配給類型別名,甚至只是將keyof表達式括keyof ,則該咒語被破壞並且映射的類型不再是同態的:

type MyBadMappedObj = { [K in (keyof MyObj)]: { value: MyObj[K] } }
/* type MyMappedObj = {
    a: { // not optional
        value: string | undefined; 
    } 
    b: { // not readonly
        value: number;
    };
} */

因此,映射{[K in keyof T]: ...}應該在輸出中保留T的結構。


不幸的是,當引入映射數組/元組功能時,看起來這僅在T是泛型類型參數時實現,而不是針對特定的具體類型。 此評論中,實施者說:

這里的問題是,當我們為元組或數組實例化通用同態映射類型時,我們僅映射到元組和數組類型(請參閱#26063 )。 我們可能也應該對keyof T同態映射類型執行此操作,其中T是非泛型類型。

這就是現在的情況。 也許這最終會得到解決。 在那之前,您可能應該使用像您的Working示例這樣的中間泛型類型作為解決方法。


Playground 鏈接到代碼

元組和數組類型只為同態映射類型保留。 同態映射類型是映射keyof T的類型,其中 T 是類型的類型參數,或K ,其中K是類型的類型參數, K extends keyof T 此行為在PR中進行了描述,該PR在映射類型中添加了保留元組和數組。

在沒有特別保留的情況下,在映射元組時,所有屬性都被映射,包括length ,您會得到不太有用的結果。

暫無
暫無

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

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