当我将类分配给接口时,为什么TypeScript不抱怨,其中接口是类的超集。
示例:
interface AI {
hello(msg: string | number): void;
}
class A {
hello(msg: string) {}
}
const a = new A();
const b: AI = new A(); // Why not complain here?
a.hello(1); // Argument of type 'number' is not assignable to parameter of type 'string'.
b.hello(1);发布于 2022-03-10 02:32:08
在TypeScript中,方法总是被选中双变,这意味着允许您扩展它们的参数类型,这是安全的,或者缩小了它们的参数类型,这是不安全的,如下所示:
interface Iface {
method(msg: string | number): void; // method syntax
}
const obj: Iface = {
method(msg: string) { msg.toUpperCase() } // okay?!
}
obj.method(1); // runtime error在本例中,Iface有一个需要接受string | number的method(),但是obj (作为Iface的注解 )有一个只接受string的method()。编译器不会对此发出警告,您将得到一个运行时错误。这似乎正是TypeScript应该避免的事情,但是(根据文献资料),在实践中,人们很少使用双变量方法来做这样不安全的事情。相反,人们倾向于这样做:
class Base {
constructor(public name: string) { }
compare(other: Base) {
return this.name.localeCompare(other.name)
}
}
class Subclass extends Base {
constructor(name: string, public age: number) { super(name); }
compare(other: Subclass) {
return (this.age - other.age) || this.name.localeCompare(other.name)
}
}Subclass的compare()方法在BaseClass的compare()方法接受任何Base时只接受Subclass在技术上是不安全的。但是做这种事情是非常有用和常见的,而且只要不把Subclass向上推到Base,你就不会直接观察到安全漏洞。
无论如何,如果您对防止这种情况感兴趣,可以打开编译器选项 (编译器选项套件的一部分)和重构,以便将任何违规的方法声明重写为函数值属性声明:
interface Iface {
method: (msg: string | number) => void; // function-valued prop syntax
}
const obj: Iface = {
method(msg: string) { msg.toUpperCase() } // error!
//~~~~ <-- Type 'string | number' is not assignable to type 'string'.
}现在,如果不安全地缩小实现中的方法参数,您将得到警告。注意,您仍然可以通过方法语法实现该方法;obj的method属性不是箭头函数,您仍然可以得到所需的错误。
https://stackoverflow.com/questions/71417022
复制相似问题