TypeScript 中的接口与类型

新手上路,请多包涵

TypeScript 中的这些语句( interface vs type )有什么区别?

 interface X {
    a: number
    b: string
}

type X = {
    a: number
    b: string
};

原文由 user6101582 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 898
2 个回答

2021 年 3 月更新:较新的 TypeScript 手册(在下面的 nju-clc 答案中 也提到过)有一节 Interfaces vs. Type Aliases 解释了差异。


原始答案(2016)

根据 (现已存档)TypeScript 语言规范

与总是引入命名对象类型的接口声明不同, 类型别名声明 可以引入任何类型的名称,包括原始类型、联合类型和交集类型。

该规范继续提到:

接口类型 与对象类型文字的类型别名有许多相似之处,但由于接口类型提供了更多功能,因此它们通常比类型别名更受欢迎。例如接口类型

interface Point {
    x: number;
    y: number;
}

可以写成类型别名

type Point = {
    x: number;
    y: number;
};

但是,这样做意味着会丢失以下功能:

  • 接口可以在 extends 或 implements 子句中命名,但对象类型字面量的类型别名自 TS 2.7 起不能再为真。
  • 一个接口可以有多个 合并的声明,但对象类型文字的类型别名不能。

原文由 Binary Birch Tree 发布,翻译遵循 CC BY-SA 4.0 许可协议

想加我的2美分;

我曾经是 “接口爱好者” (更喜欢 interfacetype 除了联合、交叉点等)…… 直到 我开始使用“任何键值对象”类型又名 Record<string, unknown>

如果您键入“任何键值对象”:

 function foo(data: Record<string, unknown>): void {
  for (const [key, value] of Object.entries(data)) {
    // whatever
  }
}

如果你使用 interface 你可能会走到死胡同

interface IGoo {
  iam: string;
}

function getGoo(): IGoo {
  return { iam: 'an interface' };
}

const goo = getGoo();

foo(goo); // ERROR
// Argument of type 'IGoo' is not assignable to parameter of type
// 'Record<string, unknown>'.
//  Index signature for type 'string' is missing in type
// 'IGoo'.ts(2345)

type 就像一个魅力:

 type Hoo = {
  iam: string;
};

function getHoo(): Hoo {
  return { iam: 'a type' };
}

const hoo = getHoo();

foo(hoo); // works

这个特殊的用例 - IMO - 有所作为。

原文由 Manu Artero 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进