本文共 4692 字,大约阅读时间需要 15 分钟。
typescript 模块
Before getting into module augmentation, let’s look at some TypeScript merging principles which will become useful as we progress.
在进行模块扩充之前,让我们看一下一些TypeScript合并原理,这些原理将随着我们的进步而变得有用。
In 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
变量同时包含bacon
和cheese
即使只有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
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
类。
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
文件中。
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
是一个模块。 为了扩展它,我们有一个使用相同名称声明的模块,在该模块中,我们将声明一个与要扩展的类相同名称的接口。 在界面中,我们将包括要添加到扩展类中的属性和方法。
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
方法的实现添加到Pet
的prototype
中。
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
接口中找到的方法和属性。
const pet = new Pet();pet.name = "Looty";pet.age = 3;pet.feed("bacon"); // baconconsole.log(pet.name = "Looty"); // Lootyconsole.log(pet.age = 3); // 3console.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 or you can use a I created just for that.
答案是,TypeScript不允许在类之间进行合并,因此我们不能创建两个或多个具有相同名称的类。 如果要合并班级,有大约使用讨论打字稿混入一种变通方法 ,也可以使用我只是创建。
That’s it. Hope this was useful. 😎👌
而已。 希望这是有用的。 😎👌
翻译自:
typescript 模块
转载地址:http://vshgb.baihongyu.com/