此为高级类型的第一部分,学习交叉类型(Intersection Types)、联合类型(Union Types)以及在使用以上类型时如何区分具体类型。javascript
交叉类型把几个类型的成员合并,造成一个拥有这几个类型全部成员的新类型。从字面上理解,可能会误认为是把取出几个类型交叉的(即交集)成员。java
交叉类型的使用场景:Mixins、不适合用类来定义。es6
我感受,交叉类型和Mixins有一点区别:交叉类型只是一个类型声明,用于类型约束;Mixins会给类增长成员,new对象时,对象会包含增长的成员属性。
咱们看一看示例:post
改自官方示例,官方示例有2个小问题:会提示不存在属性“hasOwnProperty”;另外, es6下prototype是不能够枚举的,没法经过枚举合并类属性。
interface IAnyObject { [prop: string]: any } function extend<First extends IAnyObject, Second extends IAnyObject>(first: First, second: Second): First & Second { const result: Partial<First & Second> = {}; for (const prop in first) { if (first.hasOwnProperty(prop)) { (result as First)[prop] = first[prop]; } } for (const prop in second) { if (second.hasOwnProperty(prop)) { (result as Second)[prop] = second[prop]; } } return result as First & Second; } interface IPerson { name: string, age: number } interface IOrdered { serialNo: number, getSerialNo(): number } const personA: IPerson = { name: 'Jim', age: 20 } const orderOne: IOrdered = { serialNo: 1, getSerialNo: function () { return this.serialNo } } const personAOrdered = extend<IPerson, IOrdered>(personA, orderOne); console.log(personAOrdered.getSerialNo());
联合类型与交叉类型相似,均可以拥有多个类型的能力,区别是:联合类型一次只能一种类型;而交叉类型每次都是多个类型的合并类型。学习
联合类型在实际项目中,使用场景比交叉类型普遍得多。this
function padLeft(value: string, padding: number | string) { if (typeof padding === "number") { return Array(padding + 1).join(" ") + value; } if (typeof padding === "string") { return padding + value; } return value; } padLeft("Hello world", 4);
type Scores = 1 | 2 | 3 | 4 | 5; function rating(score: Scores) { console.log(`Set score ${score}`); } rating(3); // error // rating(6);
枚举也能够实现,可是这样更简洁。prototype
function f(sn: string | null): string { if (typeof sn === null) { return 'default'; } else { return sn; } }
type Method = 'get' | 'post';
使用联合类型时,咱们是没法知道编译时的具体类型的,因此在运行时必需要肯定类型。因此代码中须要作类型保护和类型区分。code
为何叫类型保护?由于在运行时,必须知道明确类型,不然可能会访问一个不存在的成员属性,致使程序出错。对象
自定义类型保护ip
// 先判断是否存在成员属性 if(pet.swim) { }
in操做符
// 先判断是否存在成员属性 if('swim' in pet) { }
typeof操做符
function f(sn: string | number): string { if (typeof sn === 'number') { return sn.toString(); } else { return sn; } }
instanceof操做符
// 判断实例原型 if(pet instanceof Fish) { }
类型断言
function f(sn: string | null): string { if (sn === null) { return "default"; } else { return sn; } }
联合类型应用极普遍,能够多实践。