为什么TypeScript程序员更喜欢接口而不是类型

46scxncf  于 2023-01-18  发布在  TypeScript
关注(0)|答案(4)|浏览(175)

我看到很多TypeScript开发人员过度使用接口。事实上,他们几乎什么都用它,即使他们的代码比面向对象的代码更实用。我个人更喜欢type,它更灵活,不会混淆接口是由任何类实现的还是只用于定义对象类型。与type相比,使用interface有什么优势吗?或者这是开发人员习惯做的某种遗留的事情吗?

nuypyhwy

nuypyhwy1#

type的预期用途是类型的别名,尤其是交集/并集类型。
它们不应像接口一样使用,如文档所述:
正如我们提到的,类型别名可以起到类似于接口的作用;但是,也有一些细微的差别。
一个不同之处是接口创建了一个可以在任何地方使用的新名称。类型别名不会创建一个新名称-例如,错误消息不会使用别名。在下面的代码中,在编辑器中将鼠标悬停在interfaced上将显示它返回Interface,但将显示aliased返回对象文本类型。

type Alias = { num: number }
interface Interface {
    num: number;
}
declare function aliased(arg: Alias): Alias;
declare function interfaced(arg: Interface): Interface;
lymgl2op

lymgl2op2#

一个interface是一个实体应该是什么的表示;特别是对象。
接口不仅存在于Typescript中,也存在于Java、C++......语法不同但含义相同。
海事组织:

interface是在描述对象/类时应该使用的。

type在其他人手中应该被认为是别名制造者。

bmp9r5qi

bmp9r5qi3#

我在打开@typescript-eslint/strict后开始研究这个问题,@typescript-eslint/strict启用了默认首选interfaceconsistent-type-definitions
在我的研究中,我发现an article描述了偏爱interface的一个技术原因,而不是一个固执己见的原因。
具体来说,使用类型别名声明会产生更大的.d.ts输出。
...发生这种情况的原因是因为类型别名声明可以内联,而接口总是通过名称引用。

krugob8w

krugob8w4#

没有选择接口的客观原因

TS手册明确指出这是一个偏好的问题。没有哲学原因,没有意图,没有“应该”或“不应该”。
类型别名和接口非常相似,在许多情况下,您可以在它们之间自由选择。
在大多数情况下,您可以根据个人喜好进行选择,TypeScript将告诉您是否需要某种声明。
选择接口而不是类型别名的程序员是出于习惯、个人喜好,或者是因为他们阅读了手册,看到了下面的最后一行:
如果你想要一个启发式的,使用接口,直到你需要从类型使用功能.

总有一个理由

为什么 * 历史上 * 人们有一个客观的理由在默认情况下更喜欢接口,是因为类不能实现类型别名,接口不能扩展类型别名,这个限制在PR中被解除了。
你可以在互联网上到处看到类似article(付费墙)的建议,但如上所述,今天它们毫无意义:
接口可以被实现、扩展和合并,因此它们比类型常量更受欢迎。
仍然有一些环境原因
1-能够与接口进行声明合并并不是选择接口的原因,但它有一些特定的用例,比如用d.ts文件支持不同版本的Javascript。
RegExpMatchArray就是这种情况:取决于你在tsconfig中声明的lib,你将得到一个或两个声明,并且它们将被合并:

// 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
    }
}

接口合并与模块扩充相结合,是库用户定制库的一种很好的方法。
但有几点需要注意:

  • 你永远不会真正知道接口的成员是什么,因为它可以被改变;
  • 当您以为要创建一个新接口时,可能会无意中扩展一个现有接口;
  • 接口不能扩展索引签名,除非它们自己有索引签名,因为它们是开放的,而这通常不是您想要的,并且可能非常烦人。

2-另一个更喜欢接口而不是对象类型的技术原因是扩展接口比交叉两个对象类型更有效。如果你的对象很大,它会带来不同。
3-我不相信Archimedes Trajano's answer中引用的技术原因:支持文章中使用的示例甚至无法编译,这使我相信作者无法想到发生这种内联的单一现实场景,但当d.ts文件变得难以理解时,这肯定是需要考虑的事情。
4-最后,接口对于类型级编程非常有用,但这是完全不同的讨论。

相关问题