用一个例子讲清楚,TypeScript的type、interface、class

22 阅读3分钟

在 TypeScript 中,typeinterfaceclass 是三种不同的结构,分别服务于不同的目的。以下通过一个例子和分析来说明为什么 TypeScript 在有了 type 之后,还需要 interfaceclass


1. 基本区别

  • type
    用于定义类型别名,可以是任何类型的组合,如基本类型、对象类型、函数类型、联合类型等。
  • interface
    用于定义对象的结构,更适合描述具有固定形状的对象(如方法、属性等)。
  • class
    用于定义实际的对象蓝图,既提供了运行时的构造函数功能,又可配合 TypeScript 的类型系统约束对象。

2. 场景示例

需求:

我们要定义一个User类型,描述用户的信息,并实现一个功能,验证用户的年龄是否有效。


type

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

const isValidAge = (user: User): boolean => {
  return user.age >= 0 && user.age <= 120;
};

const user1: User = { name: "Alice", age: 25 };
console.log(isValidAge(user1)); // true

优点

  • 代码简洁,适合定义简单的类型。
  • 支持联合类型和复杂类型组合。

缺点

  • type 只能作为类型的定义,无法提供运行时的功能。
  • 无法继承,也无法添加额外约束。

interface

interface User {
  name: string;
  age: number;
  getDetails(): string;
}

const user2: User = {
  name: "Bob",
  age: 30,
  getDetails() {
    return `Name: ${this.name}, Age: ${this.age}`;
  },
};

console.log(user2.getDetails()); // "Name: Bob, Age: 30"

优点

  • interface 更适合描述具有方法的对象。
  • 支持继承,可以扩展其他 interface
  • 通过扩展,能更自然地描述类的结构。

缺点

  • 无法直接描述联合类型等复杂类型组合。
  • 没有运行时的功能,仍然只是一个类型约束。

class

interface User {
  name: string;
  age: number;
  getDetails(): string;
}

class UserImpl implements User {
  name: string;
  age: number;

  constructor(name: string, age: number) {
    this.name = name;
    this.age = age;
  }

  getDetails(): string {
    return `Name: ${this.name}, Age: ${this.age}`;
  }

  isValidAge(): boolean {
    return this.age >= 0 && this.age <= 120;
  }
}

const user3 = new UserImpl("Charlie", 40);
console.log(user3.getDetails()); // "Name: Charlie, Age: 40"
console.log(user3.isValidAge()); // true

优点

  • class 提供运行时的功能,可以直接创建实例。
  • 可以实现接口 (implements) 或继承其他类 (extends)。
  • 提供封装性(如 privateprotected 修饰符)。
  • 能结合 TypeScript 的类型系统与 JavaScript 的运行时特性。

缺点

  • 稍显复杂,不适合仅用作简单类型定义。

3. 为什么需要三者

  1. type 的必要性:

    • 适合简单、灵活的类型组合(例如联合类型、交叉类型)。
    • 无需实例化,仅作为类型别名存在。
  2. interface 的必要性:

    • 更适合描述面向对象的结构(属性 + 方法)。
    • 支持继承和扩展,能轻松定义具有继承关系的类型。
    • 与类配合时,可实现强类型的设计模式。
  3. class 的必要性:

    • 提供实际的运行时功能,能通过实例化创建对象。
    • 支持面向对象特性,如继承、封装、多态。
    • 结合接口可以实现更加灵活的设计。

4. 总结与对比

特性typeinterfaceclass
用途定义类型别名定义对象的结构定义运行时对象蓝图
运行时功能
继承通过交叉类型实现支持 extends支持 extendsimplements
方法支持支持定义方法类型支持方法定义支持方法的实现
复杂组合✅(联合、交叉等)
实例化

5. 何时使用

  • type:简单类型或复杂类型组合(如联合、交叉类型)。
  • interface:描述对象的结构,特别是需要扩展的场景。
  • class:需要实例化对象并提供运行时功能的场景。

🤔:《TypeScript的class和 ES6的class有什么区别