TypeScript 中的模块扩展

在进入模块扩展之前,让我们看看一些TypeScript合并原理,这些原理将随着我们的进步而变得有用。

这篇文章中,我们谈到了与接口合并接口,此外,我们还可以将接口与类合并。

 1class Food {
 2  cheese: string;
 3}
 4
 5interface Food {
 6  bacon: string;
 7}
 8
 9const food  = new Food();
10food.bacon = "nice bacon";
11food.cheese = "sweet cheese";
12
13console.log(food); // {bacon: "nice bacon", cheese: "sweet cheese"}

在上面的例子中,我们可以看到,食品变量包含面包奶酪,尽管只有奶酪食品类中被声明。

但是如果我们的界面包含一种方法,例如怎么办?

 1class Food {
 2  cheese: string;
 3}
 4
 5interface Food {
 6  bacon: string;
 7  bake(item: string);
 8}
 9
10const food  = new Food();
11
12food.bake("cake"); // Error: food.bake is not a function

尽管如此,在intelliSense的帮助下,在食品变量上将显示烘焙方法,因为 食品界面食品将合并,称为烘焙方法会导致错误,因为界面只包含声明,而不是实现。

1Food.prototype.bake = (item) => console.log(item);

现在称之为烘焙方法将起作用。

1food.bake("cake"); // cake

输入模块增加

**模块扩展帮助我们将功能扩展到我们可能无法访问的第三方库或其他文件中的类。

假设我们有一个宠物类,具有名称属性和饲料方法。

1[label pet.ts]
2export class Pet {
3  name: string;
4
5  feed(feedType: string) {
6    console.log(feedType);
7  }
8}

然后我们决定将这个类导入到我们的 index.ts 文件中,而不是只使用Pet类中的方法和属性,我们想要添加更多的功能。

首先,我们将我们的宠物类导入到我们的index.ts文件中。

1[label index.ts]
2import { Pet } from "./pet";

./pet是一个模块.为了扩展它,我们有一个使用相同名称的模块声明,在该模块中,我们将声明与我们试图扩展的类相同的名称的界面。

1[label index.ts]
2declare module "./pet" {
3  interface Pet {
4    age: number;
5    walk(location: string);
6  }
7}

TypeScript 将合并宠物 **类和宠物 **界面,因为它们可以在同一个./pet模块中找到。

请记住,我解释说,界面不包含方法的实现,而只是它们的声明,因此,我们将将步行方法的实现添加到宠物原型

1Pet.prototype.walk = (location:string) => `Likes to walk in the ${location}`

现在我们可以调用在宠物类和新宣布的宠物界面中发现的方法和属性。

 1[label index.ts]
 2const pet = new Pet();
 3
 4pet.name = "Looty";
 5pet.age = 3;
 6
 7pet.feed("bacon"); // bacon
 8console.log(pet.name = "Looty"); // Looty
 9console.log(pet.age = 3); // 3
10console.log(pet.walk("park")); // Likes to walk in the park

现在你可能想知道,而不是宣布一个界面,然后将步行方法的实施添加到宠物原型中,为什么我们不只是声明一个同名类,以便当类被初始化时,我们将有来自两个类的方法?

答案是,TypeScript不允许类之间的合并,所以我们不能创建两个或多个类同名。

希望有用!希望有用!

Published At
Categories with 技术
Tagged with
comments powered by Disqus