TypeScript 如何扩展接口以创建接口的组合

TypeScript 如何扩展接口以创建接口的组合

在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:增强现有接口

我们经常会遇到一种情况,即我们希望通过添加额外的属性或方法来增强现有接口。扩展接口使我们能够在不直接修改原始接口的情况下实现这一点。在这个例子中,我们有一个现有的User接口,其中包含一个name属性。我们扩展了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:覆盖属性和方法

当扩展接口时,我们还可以覆盖继承自基本接口的属性和方法。这允许我们修改或为扩展接口中的特定属性或方法提供不同的实现。

在下面的示例中,我们有一个包含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!

结论

总之,通过在TypeScript中扩展接口,我们可以创建接口的组合,增强现有接口,并促进代码的可重用性。通过扩展接口,我们可以从基本接口继承属性和方法,添加额外的属性和方法,覆盖现有的属性和方法,并从多个来源组合接口。

该特性允许我们构建灵活和强大的类型系统,使我们能够在组件之间定义清晰的契约并强制类型安全性。它增强了我们代码库的模块化、可读性和可维护性,使我们更容易管理和扩展我们的应用程序。无论是扩展单个接口、组合多个接口、增强现有接口还是覆盖属性和方法,扩展接口的能力使开发人员能够创建富有表达力和可重用的代码。

Camera课程

Python教程

Java教程

Web教程

数据库教程

图形图像教程

办公软件教程

Linux教程

计算机教程

大数据教程

开发工具教程

TypeScript 精选笔记