hos*_*khi 9 oop typescript typescript-typings
箭头函数和常规函数在实现接口方面有什么区别,使得代码A导致编译时错误而代码B编译成功。
注意:在tsconfig.json所有严格类型检查选项均已启用的情况下,包括strictFunctionTypes,顺便说一句,它认为通过启用strict所有严格类型检查选项即可启用。
导致编译时错误的代码A
interface SomeInterface {
someFunction: (par1: string | undefined) => string;
}
class SomeClass implements SomeInterface {
someFunction(par1: string): string //invalid function signature
{
throw new Error('Method not implemented.');
}
}
Run Code Online (Sandbox Code Playgroud)
并且,代码B编译成功。
interface SomeInterface {
someFunction(par1: string | undefined): string;
}
class SomeClass implements SomeInterface {
someFunction(par1: string): string //invalid function signature
{
throw new Error("Method not implemented.");
}
}
Run Code Online (Sandbox Code Playgroud)
启用后--strictFunctionTypes,函数类型的参数将根据维护类型安全的需要进行逆变检查:
class SomeClass implements SomeInterface { // error here
someFunction(par1: string): string
{
return par1.toUpperCase();
}
}
const i: SomeInterface = new SomeClass(); // error here
i.someFunction(undefined); // runtime error here, par1 is undefined
Run Code Online (Sandbox Code Playgroud)
但是,正如文档中提到的:
在开发此功能的过程中,我们发现了大量本质上不安全的类层次结构,包括 DOM 中的一些。因此,该设置仅适用于以函数语法编写的函数,不适用于以方法语法编写的函数。
因此,方法类型的参数仍然进行双变检查,即协变和协变,以支持一些常见模式(尽管对于其中一些情况,泛型或多态this可能是更好的方法)。一个重要的例子是Array<T>,人们显然喜欢他们的协变数组:
interface Animal { species: string }
interface Dog extends Animal { bark(): void };
const scooby: Dog = { species: "dog", bark() { console.log("ROOBY ROO or whatevz") } };
const snoopy: Dog = { species: "dog", bark() { console.log("...") } };
function processAnimals(arr: Animal[]) {
console.log("I got " + arr.map(x => x.species).join(", ") + ".")
};
const dogs = [scooby, snoopy];
processAnimals(dogs); // okay
Run Code Online (Sandbox Code Playgroud)
这是符合人体工程学且常见的,但从技术上讲,编译器应该拒绝dogs,因为Dog[]这不是有效的Animal[](事实上,像这样的方法push()会做坏事,比如将 a 推Cat入Dog[]引擎盖下)。但如果你沿着这条路走下去,你会发现 TypeScript 到处都是不健全的,即使没有函数参数,因为属性写入也是这样。有关更多详细信息,请参阅此 Q/A。
这意味着您不会产生错误,因为使用方法语法:SomeClass2SomeInterface2
class SomeClass2 implements SomeInterface2 { // no error
someFunction(par1: string): string {
return par1.toUpperCase();
}
}
Run Code Online (Sandbox Code Playgroud)
当然,这与之前的稳健性问题完全相同:
const i2: SomeInterface2 = new SomeClass2(); // no error
i2.someFunction(undefined); // runtime error, par1 is undefined
Run Code Online (Sandbox Code Playgroud)
但事实就是这样。为了方便起见,方法在设计上不如函数安全。
| 归档时间: |
|
| 查看次数: |
841 次 |
| 最近记录: |