TypeScript详解十:类型保护

前言

本篇文章主要记录 TypeScript 中类型保护的使用。

一、简单使用?

1.typeof 类型保护

// 通过typeof判断不同类型,做不同的处理,减小了范围
namespace a {
  function test(value: number | string) {
    if (typeof value === 'number') {
      console.log(value);
    } else if (typeof value === 'string') {
      console.log(value);
    }
  }
  test('hello');
  test(100);
}

2.instanceof 类型保护

namespace b {
  class Person {};
  class Man extends Person {};
  class Woman extends Person {};
  function getName(name: Person) {
    if (name instanceof Man) {
      console.log(name);
    } else if (name instanceof Woman) {
      console.log(name);
    }
  }
}

3.null 类型保护

namespace c {
  function getFirstLetter(x: string | null) {
    // if (x == null) return '';
    // x = x || '';
    return x.charAt(0)
  }
  console.log(getFirstLetter(null));
}

4.可选链操作符

// 语法:?.
// 含义:判断该属性存在后再调用
namespace d {
  let a = {
    b: 10,
    c: function () {
      return '执行c'
    }
  };
  console.log(a?.b); // 10
  console.log(a?.c()); // 执行c
}

5.可辨识的联合类型

namespace e {
// 示例1:
  interface Success {
    class: 'success',
    type: '成功'
  }
  interface Warning {
    class: 'warning',
    type: '警告'
  }
  type Button = Success | Warning;
  function getButton(btn: Button) {
    if (btn.class === 'success') {
      console.log(btn.type);
    }
    if (btn.class === 'warning') {
      console.log(btn.type);
    }
  }
  getButton({ class: 'success', type: '成功' })

// 示例2:
  interface User {
    username: string;
  }
  type Active = { type: 'add', payload: User } | { type: 'delete', payload: number };
  function reducer(active: Active) {
    switch (active.type) {
      case 'add':
        console.log(active.payload.username);
        break;
      case 'delete':
        let id: number = active.payload;
        console.log(id);
        break;

      default:
        break;
    }
  }

// 示例3:
  interface Bird {
    swing: number
  }
  interface Dog {
    leg: number
  }
  function getNum(x: Bird | Dog) {
    if ('swing' in x) {
      console.log(x); // { swing: 12 }
    } else {
      console.log(x);
    }
  }
  getNum({ swing: 12})
}

6.自定义的类型保护

namespace f {
  interface Bird {
    leg: number;
  }
  interface Dog {
    leg: number;
  }
  // 类型谓词 处理某个参数是什么类型
  function isBird(x: Bird | Dog): x is Bird {
    // 如果为真就返回true
    return x.leg == 2;
  }
  function getAnimal(x: Bird | Dog) {
    if (isBird(x)) {
      console.log(x.leg); // 2
    } else {
      console.log(x);
    }
  }
  getAnimal({ leg: 2 })
}

7.unknown 类型保护

// unknown 是any的安全类型
// unknown和any对比
namespace g {
  // any 可以对any进行任何操作,而不需要检查类型
  let name: any;
  name = true;
  name = 'a';
  name = 1;
  name.length;
  name.foo();
  name = [];

  // unknown 未知类型 不能调用方法,访问属性,调用数组长度
  let age: unknown;
  age = true;
  age = 'a';
  age = 1;
  age = [];
  // age.foo();

  // 如果想要调用unknown上的方法和属性
  // 断言
  console.log((age as string).length);
  // typeof
  if (typeof age === 'string') {
    console.log(age.length);
  }

  // 联合类型中的unknown类型,不管和谁联合,最后返回的都是unknown
  type T1 = unknown | null;
  type T2 = unknown | undefined;
  type T3 = unknown | string;
  type T4 = unknown | number;
  type T5 = unknown | number[];

  // 交叉类型 同时满足双方的条件
  // 1)
  interface A { name: string, sex: string };
  interface B { age: number, sex: string };
  type C = A & B;
  let c: C = { name: '张三', age: 18, sex: '男' };
  // 2)
  type AA = string | number;
  type BB = string | boolean;
  type CC = AA & BB; // string

  // never是unknown的子类型
  type isNever = never extends unknown ? true : false; // true
  type keys = keyof unknown; // never

  // 映射属性的时候
  // 由于unknown不知道什么类型,因此映射的时候只能是空对象
  type getType<T> = {
    [P in keyof T]: number;
  }
  type t = getType<unknown>; // {}

  // 注意:unknown只能进行比较是否相等,不能进行其他操作。如调用函数,访问属性,运算等
}

总结

本篇文章主要介绍了 TypeScript 中的类型保护相关知识,包括 typeofinstanceofnull可选链操作符、可辨识的联合类型自定义的类型保护以及 unknown 类型保护。希望能对大家有所帮助。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

剑九_六千里

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值