初学TypeScript--interface与type的区别

470 阅读3分钟

今天我们来聊聊TS中的interface与type

interface

interface用于定义对象的结构和类型,适用于描述对象模型、类、函数等。

interface专注定义对象及内部属性,支持继承和合并,熟悉Java的小伙伴会有印象,是通过extends关键字进行继承

特点及用法

  1. interface继承type

    • interface可继承type定义的对象类型,可以组合及扩展类型。
type BasicInfo = {
  name: string;
  age: number;
};

interface Person extends BasicInfo {
  address: string;
}

const person: Person = {
  name: 'Alice',
  age: 30,
  address: '123 Main St'
};
  1. interface继承interface

啥意思?说白了就是interface可以继承其他接口,组合多个接口的属性和方法

interface Animal {
  name: string;
}

interface Bird extends Animal {
  fly(): void;
}

const parrot: Bird = {
  name: 'Polly',
  fly() {
    console.log('Flying');
  }
};
  1. interface继承class

interface可继承类的结构,但只能继承类的属性和方法签名,不包括实现。

class Vehicle {
  brand: string;
  constructor(brand: string) {
    this.brand = brand;
  }
}

interface Drivable extends Vehicle {
  honk(): void;
}

const car: Drivable = {
  brand: 'Xiaomi',
  honk() {
    console.log('Honking');
  }
};

  1. 多个相同的interface会合并

如果定义了多个相同名字的接口,他们会自动合并成一个接口

interface Person {
  name: string;
}

interface Person {
  age: number;
}

// Person 类型包含 name 和 age 属性

type

type用于定义各种类型,包括基本类型、联合类型、交叉类型等。type相较于interface更为灵活,能够描述除了对象之外的类型。

特点及用法

  1. 定义各种类型

type可以定义对象类型、联合类型、交叉类型等

type Point = {
  x: number;
  y: number;
};

type Status = 'active' | 'inactive';
  1. 没有继承机制

type不能像interface一样通过extends关键字进行继承,但可以使用交叉类型来组合多个类型。

type BasicInfo = {
  name: string;
};

type DetailedInfo = BasicInfo & {
  age: number;
};

3.不能定义两个相同的type

type不像interface,遇到名字相等的情况会默认合并,当type名字重复时会报错

image.png

  1. 不能在type中使用this

interface可以使用 this 关键字引用自身。但在type中不可使用this,不能进行这种自我引用。

原因

  • interface 是面向对象的类型系统中的一个概念,因此 this 可以用于接口来引用当前实例。
  • type 更加灵活,允许定义更广泛的类型组合,但它并不是严格面向对象的,因此没有对 this 的支持。

替代方法

如果想在 type 中模拟类似的行为,可以用交叉类型或者泛型来解决问题,但不会像 this 关键字那么简洁。例如:

type FluentType<T> = {
  value: number;
  increment(): T;
  decrement(): T;
};

class Counter implements FluentType<Counter> {
  value: number = 0;

  increment(): Counter {
    this.value++;
    return this;
  }

  decrement(): Counter {
    this.value--;
    return this;
  }
}

const counter = new Counter();
counter.increment().increment().decrement(); // 同样支持链式调用

在这种方式中,我们通过泛型 T 来返回当前类的类型,虽然和 this 的语法有所不同,但也实现了类似的效果。


小结: interface vs type

  1. 定义范围

    • interface:专注于定义对象的结构,包括类和对象的属性与方法。
    • type:可以定义对象类型、联合类型、交叉类型、映射类型等,具有更广泛的用途。
  2. 继承

    • interface:支持继承(extends),可以创建更复杂的接口。
    • type:不支持继承,但可以通过交叉类型(&)来组合多个类型。
  3. 合并

    • interface:多个同名接口会自动合并,适合扩展接口。
    • type:不支持类型合并,定义相同名称的 type 会导致错误。
  4. this 关键字

    • interface:可以使用 this 关键字引用自身。
    • type:不能使用 this 关键字。但可以通过泛型等方式来实现类似的功能。