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 扩展它)。

相关推荐
RJiazhen3 小时前
从迁移至 Rsbuild 说起,前端为什么要工程化
前端·架构·前端工程化
小红3 小时前
网络通信核心协议详解:从ARP到TCP三次握手与四次挥手
前端·神经网络
影子信息4 小时前
uniapp 日历组件 uni-datetime-picker
前端·uni-app
huangql5204 小时前
UniApp + Vite + Vue3 + TypeScript 项目中 ESLint 与 Prettier 的完整配置指南
vue.js·typescript·团队开发·代码规范
向下的大树5 小时前
npm 最新镜像,命令导致下载错误
前端·npm·node.js
宁雨桥5 小时前
Service Worker:前端离线化与性能优化的核心技术
前端·性能优化
IT_陈寒5 小时前
SpringBoot实战:这5个隐藏技巧让我开发效率提升200%,90%的人都不知道!
前端·人工智能·后端
ObjectX前端实验室5 小时前
【图形编辑器架构】节点树与渲染树的双向绑定原理
前端·计算机图形学·图形学