如何擴充套件介面以建立介面組合?


在 TypeScript 中,介面提供了一種強大的方法來定義物件的形狀並強制執行型別約束。它們允許我們指定物件必須具有的必需屬性和方法。介面的一個有趣特性是擴充套件它們的能力,這允許我們建立介面的組合。在本教程中,我們將探討如何擴充套件介面以建立繼承現有介面的屬性和方法的新介面。

語法

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

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

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

示例 1:擴充套件單個介面

讓我們從一個簡單的場景開始,在這個場景中,我們有一個名為 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

示例 2:擴充套件多個介面

在 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...

示例 3:增強現有介面

我們經常會遇到想要透過新增其他屬性或方法來增強現有介面的情況。擴充套件介面允許我們這樣做,而無需直接修改原始介面。在這個例子中,我們有一個帶有 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.

示例 4:建立組合介面

在建立組合介面時,擴充套件介面也可能很有價值,組合介面組合來自多個源的屬性和方法。當使用提供其介面的外部庫或模組時,這尤其有用。在這個例子中,我們有四個介面: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.' ]

示例 5:覆蓋屬性和方法

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

在下面的示例中,我們有一個 Animal 介面,它具有 name 屬性和 makeSound() 方法。我們擴充套件 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!

結論

總之,在 TypeScript 中擴充套件介面提供了一種強大的機制,用於建立介面組合、增強現有介面和促進程式碼可重用性。透過擴充套件介面,我們可以繼承基介面的屬性和方法,新增其他屬性和方法,覆蓋現有屬性和方法,以及組合來自多個源的介面。

此功能允許我們構建靈活且強大的型別系統,使我們能夠定義元件之間的清晰契約並強制執行型別安全。它增強了我們程式碼庫的模組化、可讀性和可維護性,使我們更容易管理和擴充套件應用程式。無論是擴充套件單個介面、組合多個介面、增強現有介面還是覆蓋屬性和方法,擴充套件介面的能力都使開發人員能夠建立富有表現力和可重用的程式碼。

更新於:2023年8月21日

246 次瀏覽

啟動您的 職業生涯

透過完成課程獲得認證

開始
廣告