TypeScript中的类型别名和接口有类似的功能。在这篇文章中,我们将讨论哪种方法最适合于不同的使用情况:
表示原始类型
类型别名可以表示原始类型,但接口不能:
type Name = string;
赢家类型别名
值得注意的是,一般来说,直接使用原始类型而不是对其进行别名更简单。
表示数组
类型别名和接口都可以表示数组。
我们来比较一下这两种方法的语法:
type Names = string[];
interface Names {
[index: number]: string;
}
类型别名的方法更简洁,更清晰。
胜利者类型别名
值得注意的是,直接使用数组类型而不是对其进行别名,往往更简单。
表示图元
赢家。类型别名可以表示元组类型,但接口不能:
type Point = [number, number];
赢家类型别名
表示函数
类型别名和接口都可以表示函数。
让我们来比较一下两种方法的语法:
type Log = (message: string) => void;
interface Log {
(message: string): void;
}
类型别名的方法更简洁、更清晰。
赢家类型别名
创建联合类型
类型别名可以表示联合类型,但接口不能:
type Status = "pending" | "working" | "complete";
代表对象
到目前为止,类型别名已经和接口擦身而过。然而,接口的优势在于代表对象。
我们来比较一下两种方法的语法:
type Person = {
name: string;
score: number;
};
interface Person {
name: string;
score: number;
}
类型别名的方法又要简洁一些,但等价运算符 (=) 可能会导致语句被混淆为变量赋值到对象字面。
赢家平手
组成对象
类型别名和接口都可以将对象组合在一起。
我们来比较一下这两种方法的语法:
type Name = {
firstName: string;
lastName: string;
};
type PhoneNumber = {
landline: string;
mobile: string;
};
type Contact = Name & PhoneNumber;
interface Name {
firstName: string;
lastName: string;
}
interface PhoneNumber {
landline: string;
mobile: string;
}
interface Contact extends Name, PhoneNumber {}
类型别名的方法更简明。
类型别名可以组合接口,反之亦然:
type Name = {
firstName: string;
lastName: string;
};
interface PhoneNumber {
landline: string;
mobile: string;
}
type Contact = Name & PhoneNumber;
不过只有类型别名可以组合联合类型:
type StringActions =
| { type: "loading" }
| { type: "loaded"; data: string[] };
type NumberActions =
| { type: "loading" }
| { type: "loaded"; data: number[] };
type Actions = StringActions & NumberActions;
胜利者类型别名
编写一个库
接口有一个重要的特性,而类型别名没有,那就是声明合并:
interface ButtonProps {
text: string;
onClick: () => void;
}
interface ButtonProps {
id: string;
}
这对于在第三方库中添加缺失的类型信息非常有用。如果你正在编写一个库,并希望允许这种能力,那么接口是唯一的选择。
胜利者接口
总结
类型别名通常比接口有更多的功能和更简洁的语法。然而,接口对对象有很好的语法,你可能已经习惯了其他语言的这个概念。
重要的是,无论使用哪种方法,都要保持一致,这样代码就不会混乱了。