在 JavaScript 中,混入是一种非常常见的模式,在这种模式中,你可以从两个对象中创建一个新对象,新对象会拥有着两个对象所有的功能。交叉类型可以让你安全的使用此种模式:
联合类型
在 JavaScript 中,你希望属性为多种类型之一,如字符串或者数组。这就是联合类型所能派上用场的地方(它使用 | 作为标记,如 string | number)。
function formatCommandline(command: string[] | string) { let line = ''; if (typeof command === 'string') { line = command.trim(); } else { line = command.join(' ').trim(); } }
类型别名
类型别名会给一个类型起个新名字,类型别名有时和接口很像,但是可以作用于原始值,联合类型,元组以及其它任何你需要手写的类型。
类型别名可以是泛型
type Container<T> = { value: T };
也可以使用类型别名来在属性里引用自己:
type Tree<T> = { value: T; left: Tree<T>; right: Tree<T>; }
类型别名看起来跟interface非常像,那么应该如何区分两者?
interface只能用于定义对象类型,而type的声明方式除了对象之外还可以定义交叉、联合、原始类型等,类型声明的方式适用范围显然更加广泛。
但是interface也有其特定的用处:
interface 方式可以实现接口的 extends 和 implemenjs
interface 可以实现接口合并声明
type Alias = { num: number } interface Interface { num: number; } declare function aliased(arg: Alias): Alias; declare function interfaced(arg: Interface): Interface;
此外,接口创建了一个新的名字,可以在其它任何地方使用。 类型别名并不创建新名字—比如,错误信息就不会使用别名。 在下面的示例代码里,在编译器中将鼠标悬停在interfaced上,显示它返回的是Interface,但悬停在aliased上时,显示的却是对象字面量类型。