typescript接口
In our previous post on TypeScript Mixins, we talked briefly about declaration merging in TypeScript. In these series of posts, we are going to go a little deeper starting with interfaces with interface declaration merging.
在上一篇有关TypeScript Mixins的文章中 ,我们简要讨论了TypeScript中的声明合并。 在这些系列文章中,我们将从与接口声明合并的接口开始更进一步。
什么是声明合并? (What is Declaration Merging?)
Declaration merging is when the TypeScript complier merges two or more types into one declaration provided they have the same name.
声明合并是指TypeScript编译器将两个或多个类型合并为一个声明,只要它们具有相同的名称。
TypeScript allows merging between multiple types such as interface
with interface
, enum
with enum
, namespace
with namespace
, etc. One notable merge that isn’t permitted is class
with class
merging. If you want a functionality like that, checkout mixins.
打字稿允许多个类型之间合并诸如interface
与interface
, enum
具有enum
, namespace
与namespace
,即是不允许的是等一个显着的合并class
与class
合并。 如果您想要这样的功能,请签出mixins 。
Let’s get started with interface
with interface
merging by looking at an example:
我们来看一个示例,开始使用具有interface
合并interface
的interface
:
interface Person {
name: string;
}
interface Person {
age: number;
}
interface Person {
height: number;
}
class Employee implements Person {
name = "Mensah"
age = 100;
height = 40
}
const employee = new Employee();
console.log(employee) // {name: "Mensah", age: 100, height: 40}
Since all the interfaces were declared with the same name, Person
, they are merged into one definition so the Employee
class contains the properties from all the interfaces.
由于所有接口都使用相同的名称Person
,因此它们被合并为一个定义,因此Employee
类包含所有接口的属性。
接口中的属性名称相同(非功能) (Same property names in interfaces (non-functions))
If any of the interfaces to be merged contain the same property name and that property isn’t a function, then the type
of the properties must be the same or else the complier will throw an error.
如果要合并的任何接口包含相同的属性名称,并且该属性不是函数,则属性的type
必须相同,否则编译器将引发错误。
interface Person {
name: string;
zipCode: string;
}
interface Person {
age: number;
zipCode: string; // acceptable
}
interface Person {
zipCode: number; // error
}
接口(功能)中的属性名称相同 (Same property names in interfaces (functions))
When the elements in the merged interfaces are functions and they have the same name, they are overloaded, that is, depending on the type
of argument passed, the appropriate function will be called.
当合并接口中的元素是函数并且它们具有相同的名称时,它们将被重载,即,根据传递的参数的type
,将调用适当的函数。
interface Person {
speak(words: string);
}
interface Person {
speak(words: number);
}
const person: Person = {
speak: (wordsOrNum) => wordsOrNum
}
console.log(person.speak("Hi")) // speak(words: string) is used
console.log(person.speak(2)) // speak(words: number) is used
When interfaces containing same-signature functions are merged, the functions in the last declared interfaces appear at the top of the merged interface and the functions declared in the first interface appear beneath.
合并包含相同签名函数的接口时,最后声明的接口中的函数会出现在合并接口的顶部,而第一个接口中声明的函数会出现在下方。
interface Person {
speak(words:string);
}
interface Person {
speak(words: any);
}
interface Person {
speak(words: number);
speak(words: boolean);
}
// This is how the final merged interface looks like
interface Person {
// functions in the last interface appear at the top
speak(words: number);
speak(words: boolean);
// function in the middle interface appears next
speak(words: any):number;
// function in the first interface appears last
speak(words: string):string;
}
The reason for this is, is that later interfaces declared have a higher precedence over the initial interfaces declared. So in our example above, speak(words: string)
will never be called because in the final merged Person
interface, speak(words: any):number
comes before speak(words: string):string
and since any
can stand for any type, it gets called even if a string
is passed as an argument
.
这样做的原因是,以后声明的接口比声明的初始接口具有更高的优先级。 因此,在上面的示例中, speak(words: string)
将永远不会被调用,因为在最终合并的Person
接口中, speak(words: any):number
在speak(words: string):string
并且any
可以代表任何类型即使将string
作为argument
传递,它也会被调用。
To prove this, when you hover over the per
variable in the code below, it will display const per: number
and not const per: string
even though we are passing in a string
argument.
为了证明这一点,当您将鼠标悬停在下面的代码中的per
变量上时,即使我们传入一个string
参数,它也会显示const per: number
而不是const per: string
。
const per = person.speak("bacon");
This is true for all interfaces expect when the same name functions parameters have a string literal as a type
. It follows the same order described above but functions with string literal types are given a higher precedence and therefore appear at the top.
当相同的名称函数参数具有字符串文字作为type
时,对于期望的所有接口都是如此。 它遵循上述相同的顺序,但是具有字符串文字类型的函数具有更高的优先级,因此出现在顶部。
It’s worth noting that, the string literals in later interfaces will appear before the initial interfaces like explained above.
值得注意的是,后面的接口中的字符串文字将出现在上述初始接口之前。
interface Person {
speak(words: number);
speak(words: "World!"); // string literal type
}
interface Person {
speak(words: "Hello"); // string literal type
}
interface Person {
speak(words: string);
}
// merged interface output.
interface Person {
// string literals are given precedence
speak(words: "Hello");
speak(words: "World!");
// the rest of the functions are arranged using the same rules.
speak(words: string);
speak(words: number);
}
That’s it. Hope this was useful. 😊😎
而已。 希望这是有用的。 😊😎
翻译自: https://www.digitalocean.com/community/tutorials/typescript-interface-declaration-merging
typescript接口