抄录于掘金小册 作者:寻找海蓝 《深入浅出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});
const a = x.a;
const b = x.b;
# 联合类型
在JavaScript中,你希望属性为多种类型之一,如字符串或数组。
z这就是联合类型所能派上用场的地方(它使用|作为标记,如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;
const c:some = 'hello';
此外类型别名可以是泛型:
type Container<T> = { value: T };
也可以使用类型别名来在属性里引用自己:
type Tree<T> = {
value: T;
left: Tree<T>
right: Tree<T>
}
类型别名看起来跟interface非常像,那么应该如何区分两者。
interface只能用于定义对象类型,而type的声明方式除了对象之外还可以定义交叉、联合、原始类型等,类型声明的方式适用范围显然更加广泛。
但是interface也有其特定的用处:
- interface方式可以实现接口的extends和implement
- interface可以实现接口合并声明
type Alias = { num: number }
interface Interface {
num: number;
}
declare function aliased(arg: Alias):Alias;
declare function interfaced(arg: Interface): Interface
此外,接口创建了一个新的名字,可以在其他任何地方使用,类型别名并不创建新名字,比如,错误信息就不会使用别名。
← 微前端iceStark nodejs子进程 →