typescript 中 interface 和 type 有什么区别

1. 定义范围不同

  • interface 仅用于定义对象 / 类的形状(结构类型),无法定义基本类型、联合类型、元组等。
  • type 可以定义任意类型,包括基本类型、联合类型、交叉类型、元组、函数类型等,用途更广泛。

示例:

// type 支持基本类型别名
type Str = string;

// type 支持联合类型
type Union = string | number;

// type 支持元组
type Tuple = [string, number];

// interface 只能定义对象结构
interface User {
  name: string;
  age: number;
}

2. 扩展方式不同

  • interface 通过extends关键字扩展其他接口或类型(仅对象类型)。
  • type 通过交叉类型(&),扩展其他类型(支持任意类型的合并)。

示例:

// interface 扩展
interface Animal {
  name: string;
}
interface Dog extends Animal {
  bark(): void;
}

// type 扩展(交叉类型)
type Animal = { name: string };
type Dog = Animal & { bark(): void };

3. 声明合并(Declaration Merging)

  • interface 支持同名声明自动合并,这是其独有的特性。
  • type 不支持同名声明合并,重复定义会直接报错。

示例:

// interface 合并:两个同名接口会合并属性
interface User {
  name: string;
}
interface User {
  age: number;
}
const user: User = { name: "Tom", age: 18 }; // 合法

// type 重复定义:报错
type User = { name: string };
type User = { age: number }; // 错误:标识符“User”重复

4. 类实现(implements)

  • interface:可以被类直接implements实现。
  • type:仅当type定义的是纯对象结构时,才能被类implements;若type包含联合类型、交叉类型等复杂类型,则无法被类实现。

示例:

// interface 被类实现
interface Shape {
  area(): number;
}
class Circle implements Shape {
  area() { return Math.PI * 5 ** 2; }
}

// type 纯对象结构可被实现
type Shape = { area(): number };
class Circle implements Shape {
  area() { return Math.PI * 5 ** 2; }
}

// type 联合类型无法被实现
type Shape = { area(): number } | { perimeter(): number };
class Circle implements Shape { // 错误:联合类型不能作为类实现的接口
  area() { return Math.PI * 5 ** 2; }
}

5. 映射类型支持

  • type:天然支持映射类型(如Readonly<T>Partial<T>),可以基于已有类型生成新类型。
  • interface:不支持映射类型语法,无法直接生成映射类型。

示例:

// type 映射类型(仅type支持)
type ReadonlyUser<T> = {
  readonly [P in keyof T]: T[P];
};
type User = { name: string; age: number };
type ReadonlyUser = Readonly<User>; // { readonly name: string; readonly age: number }

6. 函数类型定义

两者都可以定义函数类型,但语法不同:

  • interface:通过调用签名定义。
  • type:直接定义函数类型。

示例:

// interface 定义函数类型
interface Func {
  (a: number): string;
}
const fn: Func = (a) => a.toString();

// type 定义函数类型
type Func = (a: number) => string;
const fn: Func = (a) => a.toString();

如何选择?

  • 优先用interface:
    • 定义对象 / 类的结构,需要扩展或声明合并时;
    • 希望 API 更符合面向对象风格时。
  • 优先用type:
    • 定义基本类型别名、联合类型、元组、映射类型时;
    • 需要组合多种类型(交叉类型)时;
    • 定义复杂类型逻辑时。
Logo

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

更多推荐