Interface V.S. Type alias

到底是更推荐用 interface 还是 type 来定义类型呢

文章 (opens in a new tab)推荐使用 interface

两者的区别

官方文档 (opens in a new tab)说明两者是非常接近的,主要的差异就是 type 是不能被重新增加新的属性的(re-open),而 interface 是可以被扩展的:(也就是这里所说的神奇的用法:在不同的 module 去扩充 interface)

interface Window {
  title: string;
}
// 可以扩充
interface Window {
  ts: TypeScriptAPI;
}
 
const src = 'const a = "Hello World"';
window.ts.transpileModule(src, {});
type Window = {
  title: string;
};
 
type Window = {
  ts: TypeScriptAPI;
};
 
// Error: Duplicate identifier 'Window'.

以及这些不同点:

官方使用建议:For the most part, you can choose based on personal preference, and TypeScript will tell you if it needs something to be the other kind of declaration. If you would like a heuristic, use interface until you need to use features from type.

Why Prefer Interface?

可以通过 playground 分别试一下 interfacetype alias 的使用

当 type 在 IIFE 中使用 (opens in a new tab)

const read = (() => {
  type ReadCallback = (content: string) => string;
  return function (path: string, callback: ReadCallback) {};
})();

可以看到输出的 .d.ts 中的类型 ReadCallback 直接被 inline 化了

而换成 interface (opens in a new tab)之后,则直接编译报错了:interface 不会被处理成 inline,而是用他的名字去引用

这条推特 (opens in a new tab)中大家也讨论很多,将 type 改成 interface 之后,将 700 多行输出降低到了 7 行(.d.ts ts 的输出)

TS 的 Program Manager 也坚定的优先选择 interface:

Honestly, my take is that it should really just be interfaces for anything that they can model. There is no benefit to type aliases when there are so many issues around display/perf.

We tried for a long time to paper over the distinction because of people’s personal choices, but ultimately unless we actually simplify the types internally (could happen) they’re not really the same, and interfaces behave better.

可以用 lint 的方式去执行这个规范。

相关阅读: