W3Cschool
恭喜您成為首批注冊(cè)用戶
獲得88經(jīng)驗(yàn)值獎(jiǎng)勵(lì)
大家好,我是 V 哥,今天有粉絲問 V 哥,ArkTS不支持structural typing 是什么意思?ArkTS不支持接口嗎?
V哥把問題整理一下,分享給大家,尤其對(duì)TypeScript不熟的小伙伴,看到官網(wǎng)這句表述,是不是也是一頭霧水,不知所措,前端小伙伴就不用說了,出門右轉(zhuǎn)吧,因?yàn)閷?duì)你來說,這是個(gè)很簡單的問題。
首先 關(guān)于 structural typing(結(jié)構(gòu)化類型) 是 TypeScript 中的特性,我們先來介紹一下。
TypeScript 是一種靜態(tài)類型的超集于 JavaScript 的編程語言,它引入了類型系統(tǒng)來增強(qiáng)代碼的可維護(hù)性和可讀性。TypeScript 的類型系統(tǒng)基于結(jié)構(gòu)化類型(Structural Typing),這意味著類型的兼容性和等價(jià)性是基于類型實(shí)際的結(jié)構(gòu)或定義來確定的,而不是基于其名稱或聲明位置,這與像 C# 或 C 這樣的語言中的命名類型系統(tǒng)(Nominal Typing)不同。
interface Point2D {
x: number;
y: number;
}
interface Point3D {
x: number;
y: number;
z: number;
}
const point2D: Point2D = { x: 1, y: 2 };
const point3D: Point3D = { x: 1, y: 2, z: 3 };
// 將 Point3D 賦值給 Point2D
const anotherPoint2D: Point2D = point3D; // 允許,因?yàn)?Point3D 包含了 Point2D 所需的所有屬性
console.log(anotherPoint2D); // 輸出: { x: 1, y: 2, z: 3 }
我們看到在這個(gè)例子中,Point3D
包含了 Point2D
所需的所有屬性(x
和 y
),并且還有一個(gè)額外的 z
屬性。TypeScript 允許這種賦值,因?yàn)樗腔诮Y(jié)構(gòu)的。
函數(shù)類型的兼容性也遵循結(jié)構(gòu)化類型規(guī)則,函數(shù)的兼容性取決于其參數(shù)和返回類型。只要函數(shù)簽名中的其他部分匹配,就可以允許參數(shù)類型有額外的特定性或更廣泛的通用性。
type Sum = (a: number, b: number) => number;
const sum: Sum = (a, b) => a + b;
const extendedSum = (a: number, b: number, c: number) => a + b + c;
// 將 extendedSum 賦值給 newSum
const newSum: Sum = (a: number, b: number) => extendedSum(a, b, 0);
console.log(newSum(1, 2)); // 輸出: 3
我們看到在這個(gè)例子中,extendedSum
函數(shù)接受三個(gè)參數(shù),但我們只使用了前兩個(gè)參數(shù)來創(chuàng)建一個(gè)新的 Sum
類型的函數(shù) newSum
。TypeScript 允許這種賦值,因?yàn)?newSum
的結(jié)構(gòu)與 Sum
兼容。
了解了 TypeScript 是如何支持結(jié)構(gòu)化類型后,咱們就可以很好理解 ArkTS中不支持結(jié)構(gòu)化類型是什么意思了,那在 ArkTS中,不同對(duì)象是怎么兼容類型的呢?
在ArkTS中,對(duì)象的類型兼容性不是基于對(duì)象的結(jié)構(gòu)(如屬性和方法的集合)來確定的,而是基于接口或類的名義類型系統(tǒng)。
所以,如果兩個(gè)對(duì)象沒有實(shí)現(xiàn)相同的接口或繼承自相同的類,即使它們具有相同的公共API,它們也被視為完全不同的類型?。
在ArkTS中,對(duì)象的類型兼容性是基于接口或類的名義類型系統(tǒng)(Nominal Typing System),而不是基于對(duì)象的結(jié)構(gòu)(如屬性和方法的集合)來確定的。這意味著,只有當(dāng)一個(gè)對(duì)象的類型與另一個(gè)類型完全相同時(shí),它們才被認(rèn)為是兼容的。這與結(jié)構(gòu)化類型系統(tǒng)(Structural Typing System),如TypeScript中所采用的,有所不同,在結(jié)構(gòu)化類型系統(tǒng)中,如果兩個(gè)對(duì)象具有相同的形狀(即相同的屬性和方法),它們就被認(rèn)為是兼容的,即使它們的類型名稱不同。
在ArkTS中,如果有兩個(gè)類,即使它們的屬性和方法相同,但如果它們沒有相同的類聲明,它們將不被認(rèn)為是兼容的。
// 定義兩個(gè)類,它們具有相同的屬性和方法
class Animal {
name: string;
constructor(name: string) {
this.name = name;
}
speak() {
console.log(`The animal says something.`);
}
}
class Dog {
name: string;
constructor(name: string) {
this.name = name;
}
speak() {
console.log(`Woof woof!`);
}
}
// 在結(jié)構(gòu)化類型系統(tǒng)中,以下賦值是允許的,因?yàn)閮蓚€(gè)對(duì)象具有相同的形狀
// let animal: Animal = new Dog(); // 錯(cuò)誤,在ArkTS中不允許
// 在ArkTS中,上述賦值將導(dǎo)致錯(cuò)誤,因?yàn)锳nimal和Dog是不同的類,即使它們具有相同的屬性和方法。
在ArkTS中,接口之間的兼容性也是基于名義類型系統(tǒng)的。即使兩個(gè)接口具有相同的屬性和方法,它們也被認(rèn)為是不同的類型。
// 定義兩個(gè)接口,它們具有相同的屬性和方法
interface IFly {
fly(): void;
}
interface IBird {
fly(): void;
}
// 在結(jié)構(gòu)化類型系統(tǒng)中,以下賦值是允許的,因?yàn)閮蓚€(gè)接口具有相同的形狀
// let flyObject: IFly = { fly: () => console.log("Flying") } as IBird; // 錯(cuò)誤,在ArkTS中不允許
// 在ArkTS中,上述賦值將導(dǎo)致錯(cuò)誤,因?yàn)镮Fly和IBird是不同的接口,即使它們具有相同的方法。
在ArkTS中,類可以實(shí)現(xiàn)接口,但類和接口之間的兼容性是基于名義類型系統(tǒng)的。
// 定義一個(gè)接口
interface IPrint {
print(): void;
}
// 定義一個(gè)類,實(shí)現(xiàn)上述接口
class Printer implements IPrint {
print(): void {
console.log("Printing...");
}
}
// 在ArkTS中,即使Printer實(shí)現(xiàn)了IPrint接口,它們也被認(rèn)為是不同的類型。
// let printObject: IPrint = new Printer(); // 正確
// 但是,如果嘗試將IPrint賦值給Printer類型,將導(dǎo)致錯(cuò)誤。
// let printerObject: Printer = { print: () => console.log("Printing") } as IPrint; // 錯(cuò)誤
再強(qiáng)調(diào)一下,在ArkTS中,類型兼容性是基于接口或類的名義類型系統(tǒng),而不是基于對(duì)象的結(jié)構(gòu)。這意味著,只有當(dāng)兩個(gè)類型的聲明完全相同時(shí),它們才被認(rèn)為是兼容的。這與TypeScript中基于結(jié)構(gòu)的類型兼容性形成了對(duì)比。
那為什么 ArkTS 會(huì)不支持結(jié)構(gòu)化類型呢,V 哥的分析應(yīng)該是考慮以下幾個(gè)方面:
不管官網(wǎng)是基于怎樣的考慮,華為的大佬們應(yīng)該是做充分的思考后的決定,當(dāng)然也沒有說死,后續(xù)會(huì)根據(jù)實(shí)際場景和反饋,看否是重新啟用結(jié)構(gòu)化類型,好了,到此你應(yīng)該可以完全理解了,歡迎關(guān)注威哥愛編程,鴻蒙開天辟地,你我相伴同行。
Copyright©2021 w3cschool編程獅|閩ICP備15016281號(hào)-3|閩公網(wǎng)安備35020302033924號(hào)
違法和不良信息舉報(bào)電話:173-0602-2364|舉報(bào)郵箱:jubao@eeedong.com
掃描二維碼
下載編程獅App
編程獅公眾號(hào)
聯(lián)系方式:
更多建議: