箭頭函式和正則函式在實作介面上有什么區別,使得代碼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.');
}
}
并且,成功編譯的代碼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.");
}
}
游樂場鏈接
uj5u.com熱心網友回復:
與--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
但是,如檔案中所述:
在此功能的開發程序中,我們發現了大量本質上不安全的類層次結構,其中包括 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
這是符合人體工程學且常見的,但從技術上講,編譯器應該拒絕,dogs因為它Dog[]不是有效的Animal[](實際上,像push()這樣的方法會做壞事,例如將 a 推Cat入Dog[]幕后)。但是如果你沿著這條路走下去,你會發現 TypeScript 就是這樣到處都是不健全的,即使沒有函式引數,因為屬性寫入也是這樣。有關詳細說明,請參閱此 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 鏈接到代碼
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/377266.html
