Typescript中type和interface的区别

在 TypeScript 中,type(类型别名)和 interface(接口)都可以用来描述类型结构,但它们在功能、使用场景和行为上存在一些关键区别。理解这些区别有助于更合理地选择使用方式。

一、核心区别对比

特性 interface type
基本用途 主要用于定义对象 / 函数的结构("形状") 可定义任意类型(对象、基本类型、联合类型等)
扩展方式 通过 extends 关键字扩展 通过交叉类型 & 扩展
合并声明 支持同名声明自动合并 不支持,同名会报错
类型范围 仅能描述对象 / 函数类型 可描述任意类型(包括基本类型、联合类型等)
实现(implements 类可以 implements 接口 类可以 implements 非联合类型的类型别名
映射类型 不支持直接定义映射类型 支持定义映射类型

二、详细区别解析

1. 定义的类型范围不同

  • interface 只能定义对象类型或函数类型 ,无法定义基本类型(如 stringnumber)、联合类型、元组等。
  • type 可以定义任意类型,包括基本类型别名、联合类型、交叉类型、元组等。
ts 复制代码
// type 可以定义基本类型别名
type Age = number;

// type 可以定义联合类型
type Status = "active" | "inactive" | "pending";

// type 可以定义元组
type Point = [number, number];

// interface 只能定义对象/函数类型(以下正确)
interface User {
  name: string;
  age: number;
}

interface AddFn {
  (a: number, b: number): number;
}

// interface 不能定义基本类型(以下错误)
interface MyString = string; // 报错:'interface' 声明只能用于声明对象类型或接口类型

2. 扩展方式不同

  • interface 通过 extends 关键字扩展(更符合面向对象的继承语义)。
  • type 通过交叉类型 & 扩展(将多个类型合并为一个)。
ts 复制代码
// interface 扩展
interface Animal {
  name: string;
}

// 扩展 Animal 接口
interface Dog extends Animal {
  bark(): void;
}

const dog: Dog = {
  name: "Buddy",
  bark: () => console.log("Woof!"),
};


// type 扩展(交叉类型)
type AnimalType = {
  name: string;
};

// 交叉合并 AnimalType 和 新类型
type DogType = AnimalType & {
  bark(): void;
};

const dog2: DogType = {
  name: "Max",
  bark: () => console.log("Woof!"),
};

3. 合并声明(Declaration Merging)

  • interface 支持同名声明自动合并(常用于扩展第三方库的类型定义)。
  • type 不支持同名声明,重复定义会报错。
ts 复制代码
// interface 同名合并
interface User {
  name: string;
}

// 再次声明 User 接口,会自动合并
interface User {
  age: number;
}

// 合并后:{ name: string; age: number }
const user: User = {
  name: "Alice",
  age: 20,
};


// type 同名会报错
type UserType = {
  name: string;
};

type UserType = {  // 报错:标识符"UserType"重复
  age: number;
};

4. 与类的实现(implements

  • 类可以通过 implements 实现 interface非联合类型的 type
  • 不能实现联合类型的 type(因为联合类型包含多种可能结构,类无法同时满足)。
ts 复制代码
interface Shape {
  area(): number;
}

// 类实现 interface(正确)
class Circle implements Shape {
  radius: number;
  area() {
    return Math.PI * this.radius **2;
  }
}


type ShapeType = {
  area(): number;
};

// 类实现非联合 type(正确)
class Square implements ShapeType {
  side: number;
  area() {
    return this.side** 2;
  }
}


// 联合类型的 type
type UnionShape = { area(): number } | { volume(): number };

// 类无法实现联合类型(报错)
class Cube implements UnionShape {  // 报错:Cube 类型不能赋值给 UnionShape 类型
  side: number;
  volume() {
    return this.side **3;
  }
}

5. 映射类型支持

type 可以结合 in 关键字定义映射类型 (通过遍历联合类型生成新类型),而 interface 不支持。

typescript 复制代码
// 定义一个联合类型
type Keys = "name" | "age";

// type 定义映射类型(将 Keys 中的每个键转为可选属性)
type Optional<T> = {
  [K in keyof T]?: T[K];
};

type User = {
  name: string;
  age: number;
};

type OptionalUser = Optional<User>; // { name?: string; age?: number }


// interface 无法定义映射类型(以下错误)
interface OptionalInterface<T> {
  [K in keyof T]?: T[K]; // 报错:接口成员不能包含"in"表达式
}

三、使用建议

  • 优先用 interface 的场景:

    • 定义对象、函数的结构(明确 "形状")。
    • 需要通过 extends 扩展或合并声明(如扩展第三方库类型)。
    • 希望代码更符合面向对象的继承语义。
  • 优先用 type 的场景:

    • 定义基本类型别名、联合类型、元组、交叉类型。
    • 需要定义映射类型。
    • 不需要合并声明,且类型逻辑更复杂(如组合多种类型)。

总结:interface 更侧重 "结构契约" 和扩展性,type 更侧重 "类型组合" 和灵活性。实际开发中可根据具体需求选择,两者并非互斥,有时也会结合使用(如 type 定义联合类型,interface 扩展它)。

相关推荐
hpoenixf4 小时前
2026 年前端面试问什么
前端·面试
还是大剑师兰特4 小时前
Vue3 中的 defineExpose 完全指南
前端·javascript·vue.js
泯泷4 小时前
阶段一:从 0 看懂 JSVMP 架构,先在脑子里搭出一台最小 JSVM
前端·javascript·架构
mengchanmian5 小时前
前端node常用配置
前端
华洛5 小时前
利好打工人,openclaw不是企业提效工具,而是个人助理
前端·javascript·产品经理
xkxnq5 小时前
第六阶段:Vue生态高级整合与优化(第93天)Element Plus进阶:自定义主题(变量覆盖)+ 全局配置与组件按需加载优化
前端·javascript·vue.js
A黄俊辉A6 小时前
vue css中 :global的使用
前端·javascript·vue.js
小码哥_常6 小时前
被EdgeToEdge适配折磨疯了,谁懂!
前端
小码哥_常6 小时前
从Groovy到KTS:Android Gradle脚本的华丽转身
前端
灵感__idea7 小时前
Hello 算法:复杂问题的应对策略
前端·javascript·算法