TypeScript - 介面擴充套件



在 TypeScript 中,介面是定義物件形狀和強制型別約束的強大方法。它們允許我們指定物件必須具有的必需屬性和方法。介面的一個有趣特性是能夠擴充套件它們,允許我們建立介面的組合。擴充套件介面也稱為介面繼承

介面繼承允許您建立更專業的介面,這些介面繼承自其他介面的屬性和方法。

語法

使用extends關鍵字在 TypeScript 中擴充套件單個或多個介面。

interface NewInterface extends ExistingInterface {
   // Additional properties and methods
}

interface NewInterface extends Interface1, Interface2, ... {
   // Additional properties and methods
}

上面顯示了透過擴充套件現有介面建立新介面的語法。還顯示了擴充套件多個介面的語法。第二個語法是擴充套件多個介面。

擴充套件單個介面

我們可以透過擴充套件單個介面來實現單介面繼承。讓我們從一個簡單的場景開始,在這個場景中,我們有一個名為 Shape 的介面,它為各種形狀定義了一個公共屬性 color。我們希望建立一個名為 ColoredShape 的新介面,它擴充套件 Shape 並新增一個額外的屬性 name。

示例

讓我們看看擴充套件 Shape 介面以建立 ColoredShape 介面的示例。在此示例中,我們定義了具有 color 屬性的 Shape 介面。然後,我們透過擴充套件 Shape 並新增 name 屬性建立了 ColoredShape 介面。我們例項化了一個型別為 ColoredShape 的物件 square,併為 color 和 name 屬性賦值。最後,我們使用點表示法訪問並列印了 color 和 name 的值。

interface Shape {
   color: string;
}

interface ColoredShape extends Shape {
   name: string;
}

const square: ColoredShape = {
   color: "red",
   name: "Square",
};

console.log(square.color);
console.log(square.name); 

編譯後,它將生成以下 JavaScript 程式碼

var square = {
   color: "red",
   name: "Square"
};
console.log(square.color);
console.log(square.name);

輸出

red
Square

擴充套件多個介面

在 TypeScript 中,我們還可以擴充套件多個介面以建立一個新的介面,該介面組合來自所有擴充套件介面的屬性和方法。這使我們能夠透過重用現有介面來建立更復雜和更專業的介面。這有助於在 TypeScript 中實現多介面繼承。

示例

在下面的示例中,我們定義了 Printable 和 Scanable 介面,每個介面都有其各自的方法。然後,我們透過擴充套件 Printable 和 Scanable 介面並新增新的方法 copy() 建立了 MultifunctionalDevice 介面。我們在名為 Printer 的類中實現了 MultifunctionalDevice 介面,併為所有方法提供了必要的實現。最後,我們例項化了 Printer 類的物件並呼叫了 print()、scan() 和 copy() 方法。

interface Printable {
   print(): void;
}

interface Scanable {
   scan(): void;
}

interface MultifunctionalDevice extends Printable, Scanable {
   copy(): void;
}

class Printer implements MultifunctionalDevice {
   print() {
      console.log("Printing...");
   }

   scan() {
      console.log("Scanning...");
   }

   copy() {
      console.log("Copying...");
   }
}

const printer = new Printer();
printer.print(); 
printer.scan(); 
printer.copy(); 

編譯後,它將生成以下 JavaScript 程式碼

var Printer = /** @class */ (function () {
   function Printer() {
   }
   Printer.prototype.print = function () {
      console.log("Printing...");
   };
   Printer.prototype.scan = function () {
      console.log("Scanning...");
   };
   Printer.prototype.copy = function () {
      console.log("Copying...");
   };
   return Printer;
}());
var printer = new Printer();
printer.print();
printer.scan();
printer.copy();

輸出

Printing...
Scanning...
Copying...

增強現有介面

我們可能經常遇到想要透過新增其他屬性或方法來增強現有介面的情況。擴充套件介面允許我們這樣做,而無需直接修改原始介面。

示例

在此示例中,我們有一個具有 name 屬性的現有 User 介面。我們擴充套件 User 介面以建立 EnhancedUser 介面,該介面添加了 age 屬性和 greet() 方法。透過擴充套件介面,我們可以定義型別為 EnhancedUser 的物件 user,其中包含來自兩個介面的屬性和方法。

interface User {
   name: string;
}

interface EnhancedUser extends User {
   age: number;
   greet(): void;
}

const user: EnhancedUser = {
   name: "John Wick",
   age: 25,
   greet() {
      console.log(`Hello, my name is ${this.name} and I'm ${this.age} years old.`);
   }
};

user.greet();

編譯後,它將生成以下 JavaScript 程式碼

var user = {
   name: "John Wick",
   age: 25,
   greet: function () {
      console.log("Hello, my name is ".concat(this.name, " and I'm ").concat(this.age, " years old."));
   }
};
user.greet();

輸出

Hello, my name is John Wick and I'm 25 years old.

建立組合介面

在建立組合介面時,擴充套件介面也可能很有價值,這些介面組合來自多個源的屬性和方法。當使用提供其介面的外部庫或模組時,這尤其有用。

示例

在此示例中,我們有四個介面:Product、DiscountedProduct、ProductWithReviews 和 FeaturedProduct。每個介面都擴充套件了一個或多個現有介面,允許我們建立一個具有來自多個源的屬性和方法的組合介面。然後,我們定義一個型別為 FeaturedProduct 的物件 product,其中包含在擴充套件介面中定義的所有屬性。

interface Product {
   name: string;
   price: number;
}

interface DiscountedProduct extends Product {
   discount: number;
}

interface ProductWithReviews extends Product {
   reviews: string[];
}

interface FeaturedProduct extends DiscountedProduct, ProductWithReviews {
   featured: boolean;
}

const product: FeaturedProduct = {
   name: "Smartphone",
   price: 599,
   discount: 50,
   reviews: ["Great product!", "Highly recommended."],
   featured: true
};

console.log(product.featured); 
console.log(product.reviews);

編譯後,它將生成以下 JavaScript 程式碼

var product = {
   name: "Smartphone",
   price: 599,
   discount: 50,
   reviews: ["Great product!", "Highly recommended."],
   featured: true
};
console.log(product.featured);
console.log(product.reviews);

輸出

true
[ 'Great product!', 'Highly recommended.' ]

覆蓋屬性和方法

在擴充套件介面時,我們還可以覆蓋從基介面繼承的屬性和方法。這使我們能夠修改或為擴充套件介面中的特定屬性或方法提供不同的實現。

示例

在下面的示例中,我們有一個具有 name 屬性和 makeSound() 方法的 Animal 介面。我們擴充套件 Animal 介面以建立 Dog 介面。透過覆蓋 Dog 介面中的 makeSound() 方法,我們提供了特定於狗的不同實現。然後可以例項化型別為 Dog 的物件 dog,並且在呼叫時將呼叫覆蓋的方法。

interface Animal {
   name: string;
   makeSound(): void;
}

interface Dog extends Animal {
   makeSound(): void;
}

const dog: Dog = {
   name: "Buddy",
   makeSound() {
      console.log("Woof woof!");
   }
};

dog.makeSound();

編譯後,它將生成以下 JavaScript 程式碼

var dog = {
   name: "Buddy",
   makeSound: function () {
      console.log("Woof woof!");
   }
};
dog.makeSound();

輸出

Woof woof!
廣告