typescript 模块_TypeScript中的模块增强

typescript 模块

Before getting into module augmentation, let’s look at some TypeScript merging principles which will become useful as we progress.

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

In this post we talked about merging interfaces with interfaces. Additionally, we can merge interfaces with classes too. Let’s look at an example.

本文中,我们讨论了将接口与接口合并。 另外,我们也可以将接口与类合并。 让我们来看一个例子。

class Food {
  cheese: string;
}

interface Food {
  bacon: string;
}

const food  = new Food();
food.bacon = "nice bacon";
food.cheese = "sweet cheese";

console.log(food); // {bacon: "nice bacon", cheese: "sweet cheese"}

In our example above, we can see that, the food variable contains both bacon and cheese even though only cheese was declared in the Food class. This is because, the interface was merged with the class.

在上面的例子中,我们可以看到,在food变量同时包含baconcheese即使只有cheese是在宣布Food类。 这是因为接口已与类合并。

But what if our interface contains a method, for example, bake

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

class Food {
  cheese: string;
}

interface Food {
  bacon: string;
  bake(item: string);
}

const food  = new Food();

food.bake("cake"); // Error: food.bake is not a function

Though, the bake method will be shown on the food variable with the help of intelliSense, because the class Food and the interface Food will be merged, calling the bake method will result in an error because interfaces contain only declaration but not implementations. To solve this, we can add the implementation of bake to the Food prototype.

但是,由于intelliSense将合并 Food接口 Food ,因此将在food变量上显示bake方法,因为将合并 Food接口 Food ,调用bake方法将导致错误,因为接口仅包含声明而不包含实现。 为了解决这个问题,我们可以在Food原型中添加bake的实现。

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

Now calling the bake method will work.

现在调用bake方法将起作用。

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


输入模块扩充 (Enter Module Augmentation)

Module augmentation helps us to extend functionalities to third party libraries we may not have access to or classes in other files.

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

Say we have a Pet class with a name property and feed method.

假设我们有一个带name属性和feed方法的Pet类。

pet.ts
宠物
export class Pet {
  name: string;

  feed(feedType: string) {
    console.log(feedType);
  }
}

We then decide to import this class into our index.ts file but instead of using only the methods and properties in the Pet class, we want to add more functionalities. We can do that using module augmentation.

然后,我们决定将该类导入到我们的index.ts文件中,而不是仅使用Pet类中的方法和属性,而是要添加更多功能。 我们可以使用模块增强来做到这一点。

First, we import our Pet class into our index.ts file.

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

index.ts
索引
import { Pet } from "./pet";

./pet is a module. In order to extend it, we have a declare a module using the same name and in that module, we will declare an interface with the same name as the class we are trying to extend. In the interface, we will include the properties and methods we want to add to the extended class.

./pet是一个模块。 为了扩展它,我们有一个使用相同名称声明的模块,在该模块中,我们将声明一个与要扩展的类相同名称的接口。 在界面中,我们将包括要添加到扩展类中的属性和方法。

index.ts
索引
declare module "./pet" {
  interface Pet {
    age: number;
    walk(location: string);
  }
}

TypeScript will merge both the Pet class and the Pet interface because they can be found in the same ./pet module.

TypeScript将合并Pet Pet 接口,因为它们可以在同一./pet模块中找到。

But that’s not all. Remember I explained that, interfaces don’t contain implementation for methods but only their declarations. For that reason, we will add the implementation of the walk method to the prototype of Pet.

但这还不是全部。 记得我曾解释过,接口不包含方法的实现,而仅包含它们的声明。 因此,我们将把walk方法的实现添加到Petprototype中。

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

Now we can call both the methods and properties found in the Pet class and the newly declared Pet interface.

现在,我们可以调用在Pet类和新声明的Pet接口中找到的方法和属性。

index.ts
索引
const pet = new Pet();

pet.name = "Looty";
pet.age = 3;

pet.feed("bacon"); // bacon
console.log(pet.name = "Looty"); // Looty
console.log(pet.age = 3); // 3
console.log(pet.walk("park")); // Likes to walk in the park

Now you may be wondering, instead of declaring an interface then adding the implementation of walk method to the Pet prototype, why didn’t we just declare a class with the same name so that when the class is initialized, we will have methods from both classes?

现在您可能想知道,与其声明一个接口,然后将walk方法的实现添加到Pet原型中,为什么我们不只声明一个具有相同名称的类,以便在初始化该类时,我们将拥有两个方法类?

The answer is, TypeScript doesn’t allow merging between classes so we can’t create two or more classes with the same name. If you want to merge classes, there is a workaround using TypeScript mixins discussed about in this post or you can use a library I created just for that.

答案是,TypeScript不允许在类之间进行合并,因此我们不能创建两个或多个具有相同名称的类。 如果要合并班级,有大约使用讨论打字稿混入一种变通方法在这篇文章中 ,也可以使用我只是创建。

That’s it. Hope this was useful. 😎👌

而已。 希望这是有用的。 😎👌

翻译自: https://www.digitalocean.com/community/tutorials/typescript-module-augmentation

typescript 模块

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值