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

相关推荐
林强1812 小时前
前端文件预览docx、pptx和xlsx
前端
像是套了虚弱散4 小时前
DevEco Studio与Web联合开发:打造鸿蒙混合应用的全景指南
开发语言·前端·华为·harmonyos·鸿蒙
衬衫chenshan5 小时前
【CTF】强网杯2025 Web题目writeup
前端
飞翔的佩奇5 小时前
【完整源码+数据集+部署教程】【天线&水】舰船战舰检测与分类图像分割系统源码&数据集全套:改进yolo11-repvit
前端·python·yolo·计算机视觉·数据集·yolo11·舰船战舰检测与分类图像分割系统
哆啦A梦15886 小时前
点击Top切换数据
前端·javascript·vue.js
程序猿追6 小时前
Vue组件化开发
前端·html
艾德金的溪7 小时前
redis-7.4.6部署安装
前端·数据库·redis·缓存
小光学长7 小时前
基于Vue的2025年哈尔滨亚冬会志愿者管理系统5zqg6m36(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。
前端·数据库·vue.js
@PHARAOH7 小时前
WHAT - 受控组件和非受控组件
前端·javascript·react.js
生莫甲鲁浪戴7 小时前
Android Studio新手开发第二十六天
android·前端·android studio