类型别名

通过类型别名,给已有的类型取一个新的名称,该名称可以作为类型关键字使用。类型别名起简化代码的作用。

类型别名的基本用法

类型别名的定义语法如下。

type 类型别名 = 类型描述;

例如,以下代码定义了一个名为 Person 的对象类型,该类型别名可以在各个场景中复用。

type Person = {
    firstName: string,
    lastName: string
}

function introduction(person: Person) {
    console.log(`My name is ${person.firstName} ${person.lastName}`);
}

let array1: Person[] =
    [{ firstName: "Rick", lastName: "Zhong" },
{ firstName: "Alina", lastName: "Zhao" }];

类型别名不仅可用于对象类型,还可以用于任何类型。示例代码如下。

type CustomString = string;
type CustomNumber = number
type CustomFuc = () => void;
type CustomNumberArray = number[];

let a: CustomString = "a";
let b: CustomNumber = 1;
let c: CustomFuc = function () { console.log("hello"); }
let d: CustomNumberArray = [1, 2, 3];

类型别名还可以基于其他类型别名来定义新的别名类型。示例代码如下。

type A = string;
type B = A;

类型别名与接口的区别

类型别名和接口非常相似,但也有一些区别。

它们的相同点如下。

  • 都可以用于描述对象。

  • 都允许扩展(接口可以使用 extends 关键字扩展,而类型别名使用交叉类型扩展)。

接口支持使用 extends 关键字继承语法,但类型别名不能从其他接口或类型中使用 extends 关键字继承,类型别名可以使用交叉类型达到继承的效果。类型别名本身可以被其他接口和类继承。示例代码如下。

type A = { x: number };
class B implements A { x: number }
interface C extends A { }

它们的不同点如下。

  • 类型别名可以用于任何类型,但接口只能用于对象类型。

  • 接口能够声明合并,类型别名不行。

例如,以下代码中的 Person 接口中虽然有两处声明,但 TypeScript 会将其合并为具有 name 属性和 introduction() 方法的一个接口,如果将以下两个声明换为类型别名,将引起编译错误。

interface Person {
    name: string
}

interface Person {
    introduction: () => void
}