在 TypeScript 中,我试图扩展Array
我的应用程序中的特殊情况。
这是我的代码:(游乐场)
enum FruitsEnum {
Kiwi = "Kiwi",
Pear= "Pear",
DragonFruit = "DragonFruit",
}
class FruitArray extends Array<FruitsEnum | string> {
constructor(fruit: FruitsEnum, ...rest: string[]) {
console.log(`constructor: ${fruit}`);
super(fruit, ...rest);
}
}
const processFruit = (fruit: FruitArray) => {
console.log('This is the fruit', fruit);
}
const main = () => {
processFruit(['notAFruit']);
}
我不明白的是为什么 TypeScript 允许processFruit(['notAFruit'])
. 我指定processFruit()
需要一个FruitArray
,但我可以给它一个标准数组,它接受它。为什么?
TypeScript 的类型系统是结构性的,而不是名义性的。如果两个类型在结构上相同,TypeScript 会将它们视为同一类型。如果扩展接口或类而不添加任何新成员,则新接口或新类实例类型将被视为与父级相同的类型。正如 TypeScript 手册中所述,这可能会导致令人惊讶的行为。
在您的示例中,这意味着
FruitArray
被视为与 相同的类型Array<FruitsEnum | string>
,顺便说一句,它也与 是相同的类型,Array<string>
因为FruitsEnum
是 的子类型string
。因此,任何FruitArray
需要 a 的地方,astring[]
就足够了。如果您想防止这种情况,最简单的方法是添加一些成员以在
FruitArray
结构上将其与string[]
. 例如:Playground 代码链接