TypeScript的类型系统是
structural
不
nominal
。如果两个类型在结构上相同,则TypeScript将它们视为相同的类型。如果你
extend
一个接口或类,而不添加任何新成员,则新接口或新类实例类型将被视为
与父类型相同
这可能导致令人惊讶的行为,
as documented in the TypeScript Handbook
。
在你的例子中,这意味着
FruitArray
被视为与相同类型
Array<FruitsEnum | string>
,顺便说一句,也是与
Array<string>
因为
FruitsEnum
是的子类型
string
。因此,在任何地方
水果阵列
需要,a
string[]
就足够了。
如果你想防止这种情况发生,最简单的方法是将一些成员添加到
水果阵列
在结构上与
字符串[]
。例如:
class FruitArray extends Array<FruitsEnum | string> {
prop = ""; // anything to structurally distinguish from Array
constructor(fruit: FruitsEnum, ...rest: string[]) {
console.log(`constructor: ${fruit}`);
super(fruit, ...rest);
}
}
const main = () => {
processFruit(['notAFruit']); // error!
// --------> ~~~~~~~~~~~~~
// Argument of type 'string[]' is not assignable to parameter of type 'FruitArray'.
}
Playground link to code