TypeScript 中 type 与 interface 的区别详解

在 TypeScript开发中,typeinterface 是两种最常用的类型定义方式。它们都能用来描述对象的结构、函数签名等,但在实际使用中却有着微妙而重要的区别。很多初学者甚至有经验的开发者都容易混淆二者。本文将从四个方面深入解析 type(类型别名)和 interface(接口)的区别,帮助你更合理地选择使用场景。


1. 定义方式不同:类型别名 vs 接口

  • type类型别名(Type Alias),它为一个已存在的类型创建一个新的名字。本质上,它只是对某个类型的“重命名”。

    type Point = {
      x: number;
      y: number;
    };
    
  • interface接口(Interface),它用于定义对象的结构契约,强调“这个对象应该长什么样”。

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

虽然上面两个写法在功能上看起来一样,但它们的本质不同:type 是对类型的引用或组合,而 interface 是对结构的声明。


2. 扩展方式不同

两者都支持扩展已有类型,但语法不同:

  • type 使用交叉类型(&)进行扩展

    type Name = { name: string };
    type Age = { age: number };
    type Person = Name & Age; // 合并两个类型
    
  • interface 使用 extends 关键字扩展

    interface Name {
      name: string;
    }
    interface Person extends Name {
      age: number;
    }
    

此外,interface 还支持多继承:

interface A { a: string; }
interface B { b: number; }
interface C extends A, B { c: boolean; }

type 虽然也可以通过多个 & 实现类似效果,但可读性和语义不如 interface 清晰。


3. 表达能力不同:type 更灵活

这是二者最关键的差异之一:

  • type 可以为任意类型定义别名,包括:

    • 基本类型(如 stringnumber
    • 联合类型(Union Types)
    • 元组类型(Tuple)
    • 映射类型、条件类型等高级类型

    示例:

    type ID = string | number;           // 联合类型
    type Coord = [number, number];       // 元组
    type Primitive = string | boolean;   // 基本类型别名
    
  • interface 只能描述对象形状(object shape),不能表示基本类型、联合类型或元组:

    // ❌ 错误!接口不能这样用
    interface ID = string | number; // TS 报错
    interface Coord = [number, number]; // TS 报错
    

因此,当你需要定义非对象结构的类型时,必须使用 type


4. 声明合并:接口自动合并,类型别名不会

这是 interface 独有的强大特性——声明合并(Declaration Merging)

  • 如果你在同一作用域中多次声明同名的 interface,TS 会自动将它们合并成一个接口:

    interface User {
      name: string;
    }
    
    interface User {
      age: number;
    }
    
    // 等价于:
    // interface User {
    //   name: string;
    //   age: number;
    // }
    

    这一特性在扩展第三方库类型或模块增强时非常有用。

  • type 不允许重复定义:

    type User = { name: string; };
    type User = { age: number; }; // ❌ 错误:重复标识符 'User'
    

总结:如何选择?

特性typeinterface
定义对象结构
支持联合/元组/基本类型
扩展方式& 交叉类型extends
声明合并
可读性与语义更通用更面向对象

建议

  • 如果你在定义 对象结构,且可能需要 扩展或被其他模块增强,优先使用 interface
  • 如果你需要定义 联合类型、元组、映射类型 或其他复杂类型结构,请使用 type
  • 在团队项目中保持一致性:例如,React 组件的 props 通常用 interface,工具函数的返回类型常用 type

TypeScript 的设计哲学是“结构化类型系统”,typeinterface 正是这一理念下的两种互补工具。

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐