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

相关推荐
遇到困难睡大觉哈哈20 分钟前
Harmony os 静态卡片(ArkTS + FormLink)详细介绍
前端·microsoft·harmonyos·鸿蒙
用户479492835691542 分钟前
Bun 卖身 Anthropic!尤雨溪神吐槽:OpenAI 你需要工具链吗?
前端·openai·bun
p***43481 小时前
前端在移动端中的网络请求优化
前端
g***B7381 小时前
前端在移动端中的Ionic
前端
拿破轮2 小时前
使用通义灵码解决复杂正则表达式替换字符串的问题.
java·服务器·前端
whltaoin2 小时前
【 Web认证 】Cookie、Session 与 JWT Token:Web 认证机制的原理、实现与对比
前端·web·jwt·cookie·session·认证机制
Aerelin2 小时前
爬虫playwright入门讲解
前端·javascript·html·playwright
5***o5002 小时前
前端在移动端中的NativeBase
前端
灵魂学者2 小时前
Vue3.x —— 父子通信
前端·javascript·vue.js·github
1***Q7842 小时前
前端跨域解决方案
前端