编程全栈开发人员

请谈谈TypeScript中的接口(interface)和类型别名(type alias)。它们有什么区别,在哪些情况下选择哪种方式?

用 Hintsage AI 助手通过面试

答案。

这两种机制——interfacetype alias——都允许描述数据结构(对象,函数,复杂类型)。

  • 接口(Interface)——经典的接口声明。允许扩展接口,进行合并(declaration merging),便于继承。
  • 类型别名(Type alias)——创建一个新的类型别名。可以通过联接/交集组合,赋值给任何实体:基本类型、函数、元组等。

区别:

  • 可扩展性: 接口更适合对象结构,支持声明合并。
  • 灵活性: 类型别名是通用的,适合所有内容:联合(|)和交集(&)。

示例:

interface Animal { name: string } interface Dog extends Animal { bark(): void } // 联合类型的类型别名: type MyType = string | number type Cat = Animal & { purr(): void }

推荐:

  • 对于公共API——使用interface
  • 对于复杂的联合和类型别名——使用type

有陷阱的问题。

问题:是否可以在另一个文件中向通过类型别名定义的类型添加新字段?

答案:

不可以。类型别名不能在另一个文件中进行声明性扩展,而接口可以。

示例:

// main.ts type User = { name: string } // another.ts type User = { age: number } // 错误:重复标识符 // 接口: // main.ts interface User { name: string } // another.ts interface User { age: number } // 好的,User = { name: string, age: number }

由于对主题细微差别的不熟悉而导致的实际错误示例。


故事

在一个大型项目中,通过类型别名定义了通用数据结构。当需要向另一个包的现有类型添加字段时,发现类型别名不支持声明合并——不得不重写为接口,导致了延迟。


故事

一位开发人员通过接口描述了函数,然后尝试添加联合类型(字符串或函数)——发现接口不适合此操作,从而不得不将所有定义更改为带有交集/联合的类型别名。


故事

在将类型从接口更改为类型别名后,弄混了扩展的语法:试图使用extends,而不是通过&进行联合。错误出现得很晚,没能立即了解原因。