我需要遍歷通過模板文字生成的字串聯合型別。
type Foo = "Foo" | "Foo2" | "Foo3";
type Bar = "Bar" | "Bar2" | `${Foo}Type`;
我想遍歷Bar運行時的所有值。通常,這是通過<const>這樣的斷言來完成的:
const Bar = ["Bar", "Bar2"] as const;
export type BarType = typeof Bar[number];
Bar.forEach((value) => {console.log(value)});
使用模板文字嘗試此操作似乎是不可能的,因為型別在運行時不可用。
const Bar = ["Bar", "Bar2", `${Foo}Type`] as const;
如果這不可能,那么完成此設計的最佳方法是什么?
如何創建一個由另一種型別組成的型別,它可以在運行時和編譯時使用?
uj5u.com熱心網友回復:
您不能從 TypeScript 型別創建 JavaScript 值;當 TypeScript 編譯為 JavaScript 時,靜態型別系統被洗掉。所以type Fooandtype Bar將無法幫助您創建const Foo和const Bar. 您唯一的希望是創建值,然后使用它們來幫助您創建型別。
您的Foo型別很容易制作:
const Foo = ["Foo", "Foo2", "Foo3"] as const;
type Foo = typeof Foo[number];
const斷言允許編譯器跟蹤 的元素的文字型別,并且從那里您可以通過使用鍵索引Foo來獲得這些元素型別的聯合。 Foonumber
但是Bar比較棘手。這是我能想到的最簡單的方法:
const Bar = ["Bar", "Bar2", ...Foo.map(t => `${t}Type` as const)] as const;
console.log(Bar);
// const Bar: readonly ["Bar", "Bar2", ...("FooType" | "Foo2Type" | "Foo3Type")[]]
type Bar = typeof Bar[number];
// type Bar = "Bar" | "Bar2" | "FooType" | "Foo2Type" | "Foo3Type"
在這里,我使用map()陣列方法附加"Type"到Foo.
首先,請注意回呼t => `${t}Type` as const帶有自己的const斷言。這告訴編譯器您希望它弄清楚模板文字運算式 `${t}Type`作為模板文字型別的計算結果。(此行為在microsoft/TypeScript#40707中實作。)由于t推斷為 type Foo,然后`${t}Type` as const推斷為 type `${Foo}Type`,這就是您想要的。
陣列方法的TypeScript 呼叫簽名map()回傳無序陣列型別,而不是像Foo. 所以編譯器不知道,例如,第二個元素是"Foo2Type". 它只知道陣列的型別是Array<`${Foo}Type`>。如果你關心訂單,我們需要做點別的。但既然你不這樣做,這就足夠了。
無論如何,該const Bar = ["Bar", "Bar2", ...Foo.map(?) as const] as const行有另一個const斷言,它告訴編譯器跟蹤"Bar"and "Bar2"。所以Bar值的型別被推斷為:
// const Bar: readonly ["Bar", "Bar2", ...("FooType" | "Foo2Type" | "Foo3Type")[]]
所以如果你問編譯器元素型別是什么,通過索引到typeof Barwith number,你會得到:
type Bar = typeof Bar[number];
// type Bar = "Bar" | "Bar2" | "FooType" | "Foo2Type" | "Foo3Type"
如預期的。
Playground 代碼鏈接
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/514942.html
標籤:打字稿类型
