类型保护就是一些表达式,可以在编译的时候就能通过类型信息确保某个作用域内变量的类型;
类型保护就是能够通过关键字判断出分支中的类型;

typeof 类型保护

function double(input: string | number) {
  if (typeof input === 'string') console.log('string');

  if (typeof input === "number") console.log('number');
}

instanceof 类型保护

class Animal { }
class Bird extends Animal { }
class Dog extends Animal { }

function getName(animal: Animal) {
  if (animal instanceof Bird) console.log('bird');

  if (animal instanceof Dog) console.log('dog');
}

null 保护

function getFirstLetter(s: string | null) {
  // if (s === null) return ''; // 第一种方式
  // s = s || ''; // 第二种方式
  return s!.charAt(0); // 第三种强行断言不为 null,如果 s 为 null 还是会报错
}

链判断运算符

let a = { b: 2 }
let result = a?.b; // a === null ? undefined : a.b;

let x = 'b';
a?.[x];
a?.[x]()

可辨识的联合类型

interface WarningButton {
  class: 'waring',
  text1: '修改'
}
interface DangerButton {
  class: 'danger',
  text2: '删除'
}
type Button = WarningButton | DangerButton;

function getButton(button: Button) {
  if (button.class === 'waring') console.log(button);

  if (button.class === "danger") console.log(button);
}

in 操作符

interface Admin {
  name: string;
  privileges: string[];
}
interface Employee {
  name: string;
  startDate: Date;
}

function printInfo(emp: Employee | Admin) {
  if ("privileges" in emp) console.log("Privileges");

  if ("startDate" in emp) console.log("Start Date");
}

自定义的类型保护

interface Bird {
  swing: number; // 2 条腿
}
interface Dog {
  leg: number; // 4 条腿
}

// 类型谓词 parameterName is Type
// 自定义类型判断 y 是 Bird,返回值为 true => y 是 Bird 类型
const isBird = (y: Bird | Dog): y is Bird => (y as Bird).swing === 2;

function getAnimal(x: Bird | Dog) {
  if (isBird(x)) console.log('bird');
  else console.log('dog');
}
// 用 TypeScript 的另一个特性泛型,来解决复用问题
function isNil<T>(v: T | undefined | null): v is undefined | null {
  return v === undefined || v === null;
}

function numberFun(v: number | undefined | null) {
  // number 类型
  if (!isNil(v)) console.log(Math.round(v));
}
function stringFun(v: string | undefined | null) {
  // string 类型
  if (!isNil(v)) console.log(v.toLocaleLowerCase());
}

unknown

// 任何类型的值可以赋值给 any,同时 any 类型的值也可以赋值给任何类型
let value: any;
value = true;
value = 1;
value = [];
value.foo()
value.length;

// unknown:是 any 的安全类型
// 任何类型的值都可以赋值给 unknown,但 unknown 只能赋值给 unknown 和 any 类型
let value2: unknown;
value2 = true;
value2 = 1;
value2 = [];
value2 = 'hello';
value2.foo();  // 对象的类型为 "unknown"
value2.length; // 对象的类型为 "unknown"

联合类型中的 unknown 类型

// 联合类型中的 unknown 不管跟谁联系,最后都是 unknown
type U1 = unknown | null;
type U2 = unknown | undefined;
type U3 = unknown | string;
type U4 = unknown | number[];

打赏作者
您的打赏是我前进的动力
微信
支付宝
评论

中午好👏🏻,我是 ✍🏻   疯狂 codding 中...

粽子

这有关于产品、设计、开发的问题和看法,还有技术文档和你分享。

相信你可以在这里找到对你有用的知识和教程

了解更多

目录

  1. 1. typeof 类型保护
  2. 2. instanceof 类型保护
  3. 3. null 保护
  4. 4. 链判断运算符
  5. 5. 可辨识的联合类型
  6. 6. in 操作符
  7. 7. 自定义的类型保护
  8. 8. unknown
  9. 9. 联合类型中的 unknown 类型