# 高级类型之交叉类型、联合类型、类型别名
本节我们要真正进入 TypeScript 的新阶段了,因为从现在开始我们要接触高级类型.
# 交叉类型
交叉类型是将多个类型合并为一个类型。 这让我们可以把现有的多种类型叠加到一起成为一种类型,它包含了所需的所有类型的特性。
在 JavaScript 中,混入是一种非常常见的模式,在这种模式中,你可以从两个对象中创建一个新对象,新对象会拥有着两个对象所有的功能。
交叉类型可以让你安全的使用此种模式:
interface IAnyObject {
[prop: string]: any
}
function mixin<T extends IAnyObject, U extends IAnyObject>(first: T, second: U): T & U {
const result = <T & U>{};
for (let id in first) {
(<T>result)[id] = first[id];
}
for (let id in second) {
if (!result.hasOwnProperty(id)) {
(<U>result)[id] = second[id];
}
}
return result;
}
const x = mixin({ a: 'hello' }, { b: 42 });
// 现在 x 拥有了 a 属性与 b 属性
const a = x.a;
const b = x.b;
@前端进阶之旅: 代码已经复制到剪贴板
# 联合类型
在 JavaScript 中,你希望属性为多种类型之一,如字符串或者数组。
这就是联合类型所能派上用场的地方(它使用 | 作为标记,如 string | number)。
function formatCommandline(command: string[] | string) {
let line = '';
if (typeof command === 'string') {
line = command.trim();
} else {
line = command.join(' ').trim();
}
}
@前端进阶之旅: 代码已经复制到剪贴板
联合类型表示一个值可以是几种类型之一,我们用竖线(|)分隔每个类型,所以number | string | boolean表示一个值可以是number、string、或boolean。
# 类型别名
类型别名会给一个类型起个新名字,类型别名有时和接口很像,但是可以作用于原始值、联合类型、元组以及其它任何你需要手写的类型.
你可以使用 type SomeName = someValidTypeAnnotation的语法来创建类型别名:
type some = boolean | string
const b: some = true // ok
const c: some = 'hello' // ok
const d: some = 123 // 不能将类型“123”分配给类型“some”
@前端进阶之旅: 代码已经复制到剪贴板
此外类型别名可以是泛型:
type Container<T> = { value: T };
@前端进阶之旅: 代码已经复制到剪贴板
也可以使用类型别名来在属性里引用自己:
type Tree<T> = {
value: T;
left: Tree<T>;
right: Tree<T>;
}
<
