如何防止TypeScript中意外的类型兼容性
假设我们有一个界面如何防止TypeScript中意外的类型兼容性,typescript,Typescript,假设我们有一个界面Animal interface Animal { amountOfLegs: number; } 然后两个不同的类实现了这个接口,Dog和Snake: class Dog implements Animal { constructor(public amountOfLegs: number) { } } class Snake implements Animal { amountOfLegs: number; constructor() {
Animal
interface Animal {
amountOfLegs: number;
}
然后两个不同的类实现了这个接口,Dog
和Snake
:
class Dog implements Animal {
constructor(public amountOfLegs: number) {
}
}
class Snake implements Animal {
amountOfLegs: number;
constructor() {
this.amountOfLegs = 0;
}
}
然后我们要创建一个特定于Snake的函数:
function functionSpecificForSnake(snake: Snake): any {
//Do something with the snake object...
}
但当使用Dog对象调用函数时,TS不会抱怨类型错误:
functionSpecificForSnake(new Dog(4)); // No compiler error, but possible runtime error?
所以我的问题是:我能阻止这种行为吗?我知道这叫什么,但我看不出有什么办法可以阻止它。在我的tsconfig.json中使用
“strictFunctionTypes”:true
选项似乎没有任何作用。我相信TypeScript会检查属性类型,所以您的问题是Dog
和Snake
具有相同的属性和类型。。。所以它们是相同的
看
界面动物{
Amontoflegs:数字;
}
狗类动物{
构造函数(公共数量:个){
}
}
蛇类动物{
公共数量:数量;
公害:布尔;
构造函数(){
该值为0.Amontoflegs=0;
这是真的;
}
}
函数functionSpecificForSnake(snake:snake):无效{
//用蛇形物体做点什么。。。
}
福斯纳克(新狗(4));
目前来看,不,你不能。在您引用的链接中:“要检查y是否可以分配给x,编译器将检查x的每个属性,以在y中找到相应的兼容属性”。因此编译器忽略类的“实现接口”位,只查看每个类的形状 蛇和狗是同一个形状,因此可以相互分配 您可以尝试为每个类添加一个鉴别器,例如:
interface Animal {
disc: string
amountOfLegs: number;
}
class Dog implements Animal {
disc = 'Dog' as const
constructor(public amountOfLegs: number) {
}
}
class Snake implements Animal {
disc = 'Snake' as const
amountOfLegs: number;
constructor() {
this.amountOfLegs = 0;
}
}
function functionSpecificForSnake(snake: Snake): any {
//Do something with the snake object...
}
functionSpecificForSnake(new Dog(4))
现在给出了错误
“Dog”类型的参数不能分配给“Snake”类型的参数。
属性“disc”的类型不兼容。
类型“Dog”不可分配给类型“Snake”(2345)您的类
Dog
和Snake
是等效的类型,因此就类型脚本而言,它们可以相互分配。您想要的行为是类型脚本没有的行为,但是您可以通过将类型更改为结构上不同的类型来模拟它
为此,您可以添加一个名为\uu brand
的属性,它不会与类型可能具有的任何不动产冲突,并且该属性可以为每个类具有不同的类型;它可以是类本身,也可以是作为字符串文本的类名称。为了避免运行时的任何开销,您可以在不初始化属性的情况下声明该属性,因此该属性实际上并不存在,但Typescript认为它确实存在。要禁用未初始化属性的错误,可以将该属性设置为可选(或使用)
类狗实现动物{
私人只读品牌:狗;
构造函数(公共amountflegs:number){}
}
蛇类动物{
私人只读品牌:Snake;
Amontoflegs:数字;
构造函数(){
该值为0.Amontoflegs=0;
}
}
然后,如果您尝试在需要使用蛇的地方使用狗,您将得到一个类型错误,因为品牌属性的类型错误
我建议在您的问题中添加一个指向打字脚本的链接@sunknudsen完成