是否可以检索扩展的泛型类型的值,例如string[]
?我的用例是判断此"数组"中是否包含给定值:
function isC<C extends string[]>(attribute: string): attribute is C[number] {
const valueSet: Set<string> = new Set(C)
return valueSet.has(attribute)
}
是否可以检索扩展的泛型类型的值,例如string[]
?我的用例是判断此"数组"中是否包含给定值:
function isC<C extends string[]>(attribute: string): attribute is C[number] {
const valueSet: Set<string> = new Set(C)
return valueSet.has(attribute)
}
当TypeScript被编译成JavaScript时,TypeScript的类型系统是erased,JavaScript是实际运行的.因此,您的函数编译为
function isC(attribute) {
const valueSet = new Set(C); // <-- this C doesn't exist
return valueSet.has(attribute);
}
这就是编译器警告您的问题.JavaScript代码中没有C
这样的东西.C
只是type,并且该类型在运行时不存在.为了使其在运行时有意义,您需要有一个类型为C
的value.可能是这样:
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");
}
不过,请注意,可能可以调整特定的实现.没有理由需要跟踪实际的数组类型,您只需要元素的字符串literal types.将数组中的所有元素放入Set
,然后再执行has()
是一种过度杀伤力,因为一旦发现有问题的元素,就可以停止判断array.因此,我建议:
function isC<C extends string>(cArray: C[], attribute: string): attribute is C {
return (cArray as readonly string[]).includes(attribute);
}
这同样有效.