一、TypeScript-联合类型和类型保护
1. 联合类型
- 什么是联合类型
- 联合类型(Union Types)表示取值可以为多种类型中的一种。
- 联合类型使用
|
分隔每个类型。
let testNumber: string | number; testNumber = 'six'; testNumber = 8; // 这里的string | number的含义是,允许testNumber的类型是string或者number,但是不能是其他类型。
- 访问联合类型的属性或方法
-
当TypeScript不确定一个联合类型的变量到底是哪个类型的时候,我们只能访问联合类型的所有类型里共有的属性或方法。
interface Bird { fly: boolean; sing: () => {}; } interface Dog { fly: boolean; bark: () => {}; } function trainAnialCommon(animal: Bird | Dog) { animal.fly; }
-
联合类型的变量在被赋值的时候,会根据类型推论的规则推断出一个类型。
interface Bird { fly: boolean; age: number; sing: () => {}; } interface Dog { fly: boolean; age: string; bark: () => {}; } function trainAnialCommon(animal: Bird | Dog) { animal.fly; animal.age = "13"; // 推断出string console.log(animal.age.length); // 所有有length属性 animal.age = 13; // 推断出是number console.log(animal.age.length); // 编译报错,类型number上不存在length属性 }
-
2. 类型保护
-
什么是类型保护
- 类型保护就是一些表达式,它们会在运行时检查以确保在某个作用域里的类型。
-
为什么需要类型保护
- 正如上文出现的联合类型,当一个变量具备多种类型的时候,虽然我们知道代表着什么类型,但是编译器是死的,它是无法知道具体的类型,这个时候就需要我们手动就处理,保护我们的程序能够正常编译运行。
-
怎么实现类型保护?
-
方式一: 使用as 类型断言的方式
interface Bird { fly: boolean; age: number; sing: () => {}; } interface Dog { fly: boolean; age: string; bark: () => {}; } /** * 使用as 类型断言的方式 * @param animal */ function trainAnial(animal: Bird | Dog) { // 写法一 if (animal.fly) { (animal as Bird).sing(); } else { (animal as Dog).bark(); } // 写法二 if (animal.fly) { (<Bird>animal).sing(); } else { (<Dog>animal).bark(); } }
-
方式二:in 语法来做类型保护
/** * in 语法来做类型保护 * @param animal */ function trainAnialSecond(animal: Bird | Dog) { if ("sing" in animal) { animal.sing(); } else { animal.bark(); } }
-
方式三:typeof 语法来做类型保护
/** * typeof 语法来做类型保护 * @param first * @param second */ function add(first: string | number, second: string | number) { if (typeof first === "string" || typeof second === "string") { return `${first}${second}`; } return first + second; }
-
方式四:使用 instanceof 语法来做类型保护
/** * 使用 instanceof 语法来做类型保护 */ class NumberObj { conut: number; } function addSecond(first: object | NumberObj, second: object | NumberObj) { if (first instanceof NumberObj && second instanceof NumberObj) { return first.conut + second.conut; } return 0; }
-