typeof 类型保护

  1. /* typeof 类型保护 */
  2. // TS会在编译阶段检查typeof类型保护
  3. function double(input: string | number | boolean) {
  4. if (typeof input === 'string') { // 这个分支是联合类型 string | number | boolean
  5. return input + input;
  6. } else {
  7. console.log(input);
  8. if (typeof input === 'number') { // 这个分支是联合类型 number | boolean
  9. return input * 2;
  10. } else {
  11. return !input; // 这个分支是boolean
  12. }
  13. }
  14. }

image.png

答案

5
2

解析

本题比较简单,主要学会 typeof 的使用。
通过 typeof 类型保护,此块级作用中,value 类型为 string。
if (typeof value === ‘string’) { }
通过 typeof 类型保护,此块级作用中,value 类型为 number。
else if (typeof value === ‘number’) { }
正确答案为 5,2。

instanceof 类型保护

// TS会在编译阶段检查instanceof类型保护
class Animal { 
    name: string
}
class Cat extends Animal {
    tailLength: number
}
function printName(animal: Animal) {
    if (animal instanceof Cat) {    // 这个分支判断是Animal
        console.log(animal.tailLength); // 这个分支里面是Cat
    } else {
        console.log(animal.name);   // 这个分支里面是Animal
    }
}

image.png

答案

10
bamboo

解析

类 Panda 和类 Koala 继承自父类 Animal。
因此,在函数 animalInfo 中,形参 animal 可以接受子类 Panda 和 Koala
通过 instanceof 类型保护,此块级作用中,animal 类型为 Panda。
if (typeof value === ‘Panda’) { }
通过 instanceof 类型保护,此块级作用中,animal 类型为 Koala。
else if (typeof value === ‘Koala’) { }
因此,当 animal 类型为 Koala 时。
… new Koala(‘koala’, 10) … animal.getAge() // 10
因此,当 animal 类型为 Koala 时。
… new Panda(‘panda’, ‘bamboo’) … animal.getFood() // bamboo

null 类型保护

/* null 类型保护 */
// TS是通过关键字判断分支中的变量类型
// 如果tsconfig.json中的strictNullChecks为true,这个方法会报错,因(s)是null没有string方法
function getFirstLetter_5203(s: string | null) {
    return s.charAt(0);
}

// 所以需要判断s是否为null
// 第一种方法
function getFirstLetter_5204(s: string | null) {
    if (s === 'null') {
        return ''
    }
    return s.charAt(0);
}

// 第二种方法
function getFirstLetter_5205(s: string | null) {
    s = s || '';
    return s.charAt(0);
}

// 特例场景
function getFirstLetter_5206(s: string | null) {
    function append(input: string) {
        return s!.trim() + input    // 新版本这个分支是string,旧版本采用!语法来排除null
    }
    s = s || '';
    append(s)
    return s.charAt(0);
}

image.png

答案

A B C

解析

函数 getLength 接收的参数为 string | null
在选项 A 中,name.length 的 name 只可能是 string,故正确。
同理选项 B 也是正确的。
// _name 的类型为 string const _name = name || ‘’;
选项 C 也是正确的。

可辨识联合

/* 可辨识联合 */
interface TipOption {
    type: 'tip' // 可辨识的属性
    text: string
}
interface AlertOption {
    type: 'alert'   // 可辨识的属性
    success(): void
}
interface ConfirmOption {
    type: 'confirm' // 可辨识的属性
    success(): void
    failure(): void
}

type Option = TipOption | AlertOption | ConfirmOption   // 联合,所以是可辨识联合
function show(option: Option) {
    if (option.type === 'tip') {
        console.log(option.text);
    } else if (option.type === 'alert') {
        console.log(option.success());
    } else {
        console.log(option.failure());
    }
}

image.png

答案

panda
10

解析

题目中,可辨识联合的特征(标签)是 key。
函数 getAnimalInfo 的形参 animal 的类型为 Panda | Koala

if (animal.key === 'panda') {
    // 辨识出此时 animal 类型为 Panda
    return animal.name;
}

else if (animal.key === 'koala') {
    // 辨识出此时 animal 类型为 Koala
    return animal.age;
}

所以答案为 panda,10。