javascript - 獲取擴展數組的泛型參數的值
是否有可能檢索一個泛型類型的值,該泛型類型繼承自,例如,string[]?我的使用案例是檢查給定的值是否包含在這個「陣列」中:
function isC<C extends string[]>(attribute: string): attribute is C[number] {
const valueSet: Set<string> = new Set(C)
return valueSet.has(attribute)
}
答案#1
TypeScript 的型別系統在 TypeScript 編譯成 JavaScript 時會被刪除,而實際執行的是 JavaScript。因此你的函數編譯後會成為
function isC(attribute) {
const valueSet = new Set(C); // <-- this C doesn't exist
return valueSet.has(attribute);
}
這就是編譯器警告你的問題。在你的 JavaScript 代碼中根本不存在 C。C 只是一種 型別,而該型別在運行時並不存在。為了讓這在運行時有任何意義,你需要擁有一個 值,其型別為 C。可能像這樣:
function isC<C extends string[]>(attributes: [...C], attribute: string): attribute is C[number] {
const valueSet: Set<string> = new Set(attributes)
return valueSet.has(attribute)
}
那將會有效:
let attr = Math.random() < 0.5 ? "b" : "d";
if (isC(["a", "b", "c"], attr)) {
console.log({ a: 1, b: 2, c: 3 }[attr]);
} else {
console.log("nope");
}
不過請注意,特定的實作可能可以進行微調。沒有理由你需要追蹤實際的陣列類型,你只需要元素的字串字面值類型。而且將陣列中的所有元素放入一個Set然後再用has()來檢查是過度的,因為你一旦找到目標元素就可以停止檢查陣列。因此我建議:
function isC<C extends string>(cArray: C[], attribute: string): attribute is C {
return (cArray as readonly string[]).includes(attribute);
}
那也可以。
程式碼的 Playground 連結
