TypeScript 联合类型和类型保护
interface Bird{ fly: boolean, sing: ()=>{} } interface Dog{ fly: boolean, bark: ()=>{} } /** * animal: Bird | Dog这就是一个联合类型 * animal 既可以是 Bird 又可以是 Dog * 联合类型只提示公共的属性 */ // 第一种类型保护方案:类型断言的方式 function trainAnimal(animal: Bird | Dog) { /** * 这里直接调用 animal.sing() 是会报错的,因为 Dog 不存在 sing() * 解决这个问题第一种方案:断言 */ if (animal.fly) { (animal as Bird).sing(); // 强制告诉 TS,animal 是 Bird 类型 } (animal as Dog).bark(); } // 第二种类型保护方案:in 语法来做类型保护 function trainAnimal2(animal: Bird | Dog) { if ('sing' in animal) { // 告诉 ts animal 里面有 sing animal.sing(); } else { // 上面 animal 有sing, else 就是没有 sing, ts 可以推断出来 animal.bark(); } } // 第三种类型保护方案: typeof 语法来做类型保护 function add(first: string | number, second: string | number) { /** * 这里直接 first + second 也会报错,因为有可能他们是 string 类型 * 这个时候也可以用类型保护 */ if (typeof first === 'string' || typeof second === 'string') { return `${first}${second}`; } return first + second } // 第四种类型保护方案: instanceof 语法来做类型保护 class NumberObj { // 因为只有 class 才能用 instanceof 做类型保护 count: number } function addSecond(first: object | NumberObj, second: object | NumberObj) { /** * 这里直接 first.count + second.count 也会报错,因为有可能他们是 object,没有 count 属性 * 这个时候也可以用类型保护 */ if (first instanceof NumberObj && second instanceof NumberObj) { return first.count + second.count; } return 0; }
总结:类型保护四种方式
1、类型断言的方式 animal as Bird
2、in 语法来做类型保护 if ('sing' in animal){}
3、 typeof 语法来做类型保护 if (typeof first === 'string' || typeof second === 'string') {}
4、instanceof 语法来做类型保护 if (first instanceof NumberObj && second instanceof NumberObj) {}