TypeScript:Interface 与 Type 的区别

Interface 和 Type 的用法对比与选择建议

问题

说说你对 TypeScript 的理解,Interface 和 Type 的区别。

解答

TypeScript 是 JavaScript 的超集,添加了静态类型检查。interfacetype 都可以定义类型,但有一些关键区别。

基本用法

// interface 定义对象类型
interface User {
  name: string;
  age: number;
}

// type 定义类型别名
type UserType = {
  name: string;
  age: number;
};

// 两者使用方式相同
const user1: User = { name: 'Alice', age: 25 };
const user2: UserType = { name: 'Bob', age: 30 };

区别一:声明合并

// interface 支持声明合并
interface Animal {
  name: string;
}

interface Animal {
  age: number;
}

// 自动合并为 { name: string; age: number }
const dog: Animal = { name: 'Max', age: 3 };

// type 不支持声明合并,重复定义会报错
type Plant = { name: string };
// type Plant = { age: number }; // Error: 重复标识符

区别二:扩展方式

// interface 使用 extends 扩展
interface Person {
  name: string;
}

interface Employee extends Person {
  salary: number;
}

// type 使用交叉类型 & 扩展
type PersonType = {
  name: string;
};

type EmployeeType = PersonType & {
  salary: number;
};

// 两者可以互相扩展
interface A {
  a: string;
}
type B = A & { b: number };

type C = { c: string };
interface D extends C {
  d: number;
}

区别三:type 独有的能力

// 1. 定义联合类型
type Status = 'pending' | 'success' | 'error';
type StringOrNumber = string | number;

// 2. 定义元组
type Point = [number, number];
const p: Point = [10, 20];

// 3. 定义基本类型别名
type ID = string;
type Callback = () => void;

// 4. 使用 typeof 获取类型
const config = { api: '/api', timeout: 3000 };
type Config = typeof config; // { api: string; timeout: number }

// 5. 条件类型
type IsString<T> = T extends string ? true : false;
type A = IsString<string>; // true
type B = IsString<number>; // false

// 6. 映射类型
type Readonly<T> = {
  readonly [K in keyof T]: T[K];
};

区别四:interface 独有的能力

// interface 可以被类实现
interface Printable {
  print(): void;
}

class Document implements Printable {
  print() {
    console.log('Printing...');
  }
}

// type 也可以被实现,但只限于对象类型
type Loggable = {
  log(): void;
};

class Logger implements Loggable {
  log() {
    console.log('Logging...');
  }
}

如何选择

// 推荐使用 interface 的场景:
// 1. 定义对象结构
interface ApiResponse {
  code: number;
  data: unknown;
  message: string;
}

// 2. 需要声明合并(如扩展第三方库类型)
declare global {
  interface Window {
    myApp: { version: string };
  }
}

// 推荐使用 type 的场景:
// 1. 联合类型
type Theme = 'light' | 'dark';

// 2. 元组
type Coordinate = [number, number, number];

// 3. 复杂类型运算
type Partial<T> = { [K in keyof T]?: T[K] };

关键点

  • 声明合并:interface 支持,type 不支持
  • 扩展语法:interface 用 extends,type 用 &
  • type 更灵活:可定义联合类型、元组、基本类型别名、条件类型
  • interface 更语义化:专门用于描述对象结构,支持类实现
  • 选择建议:定义对象结构用 interface,需要类型运算用 type