本文介绍了为什么此箭头在接口中起作用而不能编译?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Arrow函数常规函数在实现接口时,代码A导致编译时出错,代码B编译成功。

注意:在tsconfig.json中启用了所有严格类型检查选项,包括strictFunctionTypes,btw假定通过启用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.');
    }
}

和代码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.");
    }
}

Playground Link

推荐答案

启用--strictFunctionTypes后,函数类型‘参数被检查contravariantly,以维护类型安全:

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

但是,如文档中所述:


因此方法类型‘参数仍然被检查bivariantly,意思是一致的和covariantly,以便支持一些常见模式(尽管对于某些情况,genericspolymorphic this可能是更好的方法)。最大的例子是Array<T>,其中人们apparently like their covariant arrays

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

这是符合人体工程学和常见的,但从技术上讲,编译器应该拒绝dogs,因为Dog[]不是有效的Animal[](实际上,像push()这样的方法会做不好的事情,比如将Cat推入引擎盖下的Dog[])。但如果沿着这条路线走下去,你会发现打字脚本完全是不正确的,即使没有函数参数,因为属性编写也是这样的。有关详细信息,请参阅this Q/A


表示SomeClass2不会产生错误,因为SomeInterface2使用方法语法:

class SomeClass2 implements SomeInterface2 { // no error
    someFunction(par1: string): string {
        return par1.toUpperCase();
    }
}

当然,这与之前的问题完全相同:

const i2: SomeInterface2 = new SomeClass2(); // no error
i2.someFunction(undefined); // runtime error, par1 is undefined

但事实就是这样。为方便起见,在设计上方法不如函数安全。

Playground link to code

这篇关于为什么此箭头在接口中起作用而不能编译?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

11-01 23:59