我看到很多 TypeScript 开发人员过度使用接口。事实上,他们几乎将它用于所有事情,即使他们的代码比面向对象更实用。就我个人而言,我更喜欢
type
,它更灵活,并且不会混淆接口是否由任何类实现或仅用于定义对象类型。
使用 interface
相对于 type
是否有任何优势,或者这是开发人员习惯做的某种遗留事情?
type
的预期用途是类型的别名,尤其是交集/联合类型。
它们不应该像接口一样使用,如文档所述:
正如我们所提到的,类型别名可以起到类似于接口的作用;但是,存在一些细微的差异。
一个区别是接口创建了一个到处使用的新名称。类型别名不会创建新名称 - 例如,错误消息不会使用别名。在下面的代码中,将鼠标悬停在编辑器中的
上将显示它返回interfaced
,但会显示Interface
返回对象文字类型。aliased
type Alias = { num: number } interface Interface { num: number; } declare function aliased(arg: Alias): Alias; declare function interfaced(arg: Interface): Interface;
interface
是实体应该是什么的表示;具体对象。
接口不仅存在于 Typescript 中,也存在于 Java、C++ 中……语法不同,但含义相同。
海事组织:
interface
是描述对象/类应该是什么时应该使用的内容。
type
在其他人手中应被视为别名创建者。
TS 手册 明确指出这是一个偏好问题。没有哲学原因,没有意图,没有“应该”或“不应该”。
类型别名和接口非常相似,在很多情况下您可以在它们之间自由选择。
大多数情况下,您可以根据个人喜好进行选择,TypeScript 会告诉您是否需要其他类型的声明。
选择接口而不是类型别名的程序员是出于习惯、个人喜好,或者是因为他们阅读了手册并看到了下面的最后一行:
如果您想要启发式方法,请使用接口,直到您需要使用类型中的功能。
历史上人们有充分的理由默认选择接口,因为类无法实现类型别名,而接口无法扩展类型别名。此限制已通过此PR解除。
您可以在互联网上看到类似这篇接口可以实现、扩展和合并,因此它们优于类型文字。仍存在情境原因
声明合并并不是选择接口默认情况下的理由,但它有情境用例,例如使用 d.ts 文件支持不同版本的 Javascript。
RegExpMatchArray
就是这种情况:根据您在
tsconfig
中声明的库,您将获得一个或两个声明,并且它们将被合并:
// from lib.es5.d.ts
interface RegExpMatchArray extends Array<string> {
/**
* The index of the search at which the result was found.
*/
index?: number;
/**
* A copy of the search string.
*/
input?: string;
/**
* The first match. This will always be present because `null` will be returned if there are no matches.
*/
0: string;
}
// from lib.es2018.regexp.d.ts
interface RegExpMatchArray {
groups?: {
[key: string]: string
}
}
与模块增强相结合,界面合并是图书馆用户自定义它的好方法。但有一些注意事项:
3-我不相信
Archimedes Trajano的回答中引用的技术原因:支持文章中使用的示例甚至无法编译,这使我相信作者无法想到这种内联将出现的单一现实场景会发生,但是当 d.ts 文件变得难以理解的大时,这肯定是需要考虑的事情。
4-最后,接口非常适合类型级编程,但这是一个完全不同的讨论。
@typescript-eslint/strict
后开始研究这个问题,它启用了
consistent-type-definitions
,默认更喜欢interface
。在我的研究中,我发现
一篇文章描述了首选interface
的“技术”原因,而不是固执己见。
内联...发生这种情况的原因是因为类型别名声明可以是
,而接口始终通过名称引用。