- 交叉类型
交叉类型是将多个类型合并为一个类型。可以把现有的多种类型叠加到为一种类型,包含了所有类型的特性。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;}
- 联合类型
联合类型和交叉类型很有关联,但是使用上却完全不同。访问共同拥有的 ```typescript interface a { fly(); layEggs(); }
interface b { swim(); layEggs(); }
function getSmallPet(): b | a { // … }
let pet = getSmallPet(); pet.layEggs(); // okay pet.swim(); // errors
3. 类型保护和区别类型```typescriptlet pet = getSmallPet();// 每一个成员访问都会报错if (pet.swim) {pet.swim();}else if (pet.fly) {pet.fly();}
类型断言使上面代码执行
let pet = getSmallPet();if ((pet as Fish).swim) {(<Fish>pet).swim();}else {(<Bird>pet).fly();}
4.用户自定义的类型保护
一旦检查过类型,之后的每个分支都清楚的知道类型。
要定义一个类型保护,我们只要简单地定义一个函数,它的返回值是一个 类型谓词:pet is Fish就是类型谓词,谓词为 parameterName is Type这种形式, parameterName必须是来自于当前函数签名里的一个参数名。
function isFish(pet: Fish | Bird): pet is Fish {return (<Fish>pet).swim !== undefined;}
// 'swim' 和 'fly' 调用都没有问题了if (isFish(pet)) {pet.swim();}else {pet.fly();}
typeof类型保护
function isNumber(x: any): x is number {return typeof x === "number";}function isString(x: any): x is string {return typeof x === "string";}function padLeft(value: string, padding: string | number) {if (isNumber(padding)) {return Array(padding + 1).join(" ") + value;}if (isString(padding)) {return padding + value;}throw new Error(`Expected string or number, got '${padding}'.`);}
不需要将typeof抽象成一个函数,ts可以识别它为一个类型保护,所以可以直接在代码里检查类型。
function padLeft(value: string, padding: string | number) {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}'.`);}
这些 typeof类型保护只有两种形式能被识别: typeof v === "typename"和 typeof v !== "typename", "typename"必须是 "number", "string", "boolean"或 "symbol"。 但是TypeScript并不会阻止你与其它字符串比较,语言不会把那些表达式识别为类型保护
