交叉类型(Intersection Types)
交叉类型是将多个类型合并为一个类型。 这让我们可以把现有的多种类型叠加到一起成为一种类型,它包含了所需的所有类型的特性。 例如, Person & Serializable & Loggable同时是 Person 和 Serializable 和Loggable。 就是说这个类型的对象同时拥有了这三种类型的成员。
我们大多是在混入(mixins)或其它不适合典型面向对象模型的地方看到交叉类型的使用。 (在JavaScript里发生这种情况的场合很多!) 下面是如何创建混入的一个简单例子:
function extend<T, U>(first: T, second: U): T & U {let result = <T & U>{};for (let id in first) {(<any>result)[id] = (<any>first)[id];}for (let id in second) {if (!result.hasOwnProperty(id)) {(<any>result)[id] = (<any>second)[id];}}return result;}class Person {constructor(public name: string) { }}interface Loggable {log(): void;}class ConsoleLogger implements Loggable {log() {// ...}}var jim = extend(new Person("Jim"), new ConsoleLogger());var n = jim.name;jim.log();
联合类型(Union Types)
联合类型与交叉类型很有关联,但是使用上却完全不同。 偶尔你会遇到这种情况,一个代码库希望传入 number或string类型的参数。 例如下面的函数:
/*** Takes a string and adds "padding" to the left.* If 'padding' is a string, then 'padding' is appended to the left side.* If 'padding' is a number, then that number of spaces is added to the left side.*/function padLeft(value: string, padding: any) {if (typeof padding === "number") {return Array(padding + 1).join(" ") + value;}if (typeof padding === "string") {return padding + value;}throw new Error(`Expected string or number, got '${padding}'.`);}padLeft("Hello world", 4); // returns " Hello world"
padLeft存在一个问题, padding参数的类型指定成了 any。 这就是说我们可以传入一个既不是 number也不是 string类型的参数,但是TypeScript却不报错。
