类型保护 在 TypeScript 中,类型保护(Type Guards)通过在运行时检查变量的类型,可以在特定的代码块中自动识别变量的属性和方法,从而确保代码的类型安全,提示并规避不合法的操作。
typeof类型保护 typeof 操作符可以用来判断基本类型,如 string、number 等。
1 2 3 4 5 6 7 8 9 10 11 function langpz( value: string | number) { value.toFixed( 2 ) // 报错 类型“string”上不存在属性“toFixed” if ( typeof value === 'string') { console.log( value.toUpperCase( ) ) } else if ( typeof value === 'number') { console.log( value.toFixed( 2 ) ) } } langpz( "hello" ) langpz( 123 .456 )
通过 typeof 操作符,我们可以对变量进行识别类型,避免调用字符串或者数字方法报错。
instanceof类型保护 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 class Cat { miao( ) { console.log( "喵喵" ) } } class Dog { wang( ) { console.log( "汪汪" ) } } const speak: ( animal: Cat | Dog) => void = ( animal) => { if ( animal instanceof Dog) { animal.wang( ) } else if ( animal instanceof Cat) { animal.miao( ) } } const dog = new Dog( ) const cat = new Cat( ) speak( dog) speak( cat)
instanceof 检查使得 TypeScript 能够在不同的代码块中识别 animal 是 Dog 还是 Cat 的实例,并调用相应的方法。
in类型保护 in 操作符用于检查对象上是否存在某个属性。它适用于检查具有不同属性的联合类型。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 interface Fish { swim (): void ; } interface Bird { fly (): void ; } function getType (animal: Fish | Bird ) { if ('swim' in animal) { animal.swim (); } else { animal.fly (); } } const fish: Fish = { swim: () => console.log ("Swimming" ) };const bird: Bird = { fly: () => console.log ("Flying" ) };getType (fish); getType (bird);
自定义类型保护 自定义类型保护通常是一个函数,它接受一个参数,并返回一个类型谓词,即一个表达式,其结果为布尔值,用于确定参数是否属于某个特定的类型。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 interface Fish { swim (): void ; } interface Bird { fly (): void ; } function isBird (animal: Fish | Bird ):animal is Bird { return 'fly' in animal } function getAniaml (animal:Fish | Bird ){ if (isBird (animal)){ animal.fly (); }else { animal.swim (); } } const fish: Fish = { swim: () => console.log ("Swimming" ) };const bird: Bird = { fly: () => console.log ("Flying" ) };getAniaml (fish); getAniaml (bird);
自定义类型保护函数 isBird 通过检查 fly 方法是否存在来识别 animal 是否为 Bird 类型。
可辨识联合类型 可辨识联合类型是一种特殊的联合类型,它允许我们根据某个字段(通常称为“标签”或“可辨识字段”)的值来区分不同的类型。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 interface Fish { kind: "fish" ; swim (): void ; } interface Bird { kind: "bird" ; fly (): void ; } type Animal = Fish | Bird ; function makeSound (animal: Animal ) { switch (animal.kind) { case "fish" : animal.swim (); break ; case "bird" : animal.fly (); break ; default : throw new Error ("Unknown animal kind" ); } } const myFish: Fish = { kind: "fish" , swim: () => console.log ("langpz fish" ) };const myBird: Bird = { kind: "bird" , fly: () => console.log ("langpz bird" ) };makeSound (myFish); makeSound (myBird);