什么是类型保护

  1. 类型保护是一种 TypeScript 技术,用于获取变量类型信息,通常使用在条件块语句中;
  2. 类型保护可以指导 TypeScript 编译器在特定的上下文中推断出变量的特定类型,确保参数的类型与你所说的一致;
  3. 类型保护通常用于 缩小类型,它非常类似于特征检测,允许检测值的正确、方法、原型和属性;
  4. 有五种主要的方式来使用类型保护:
    1. instanceof 关键字:检查一个值是否是一个类的实例;
    2. typeof 关键字:检查一个变量是否为某一类型;
    3. in 关键字:用来确定对象是否具有某个属性;
    4. 等式收缩式保护器:如果一个变量的类型未知,但它等于另一个具有精确类型的变量,那么 Typescript 会使用该已知变量提供的信息来缩小第一个变量的类型;
    5. 带有谓词的自定义类型保护:通过自己编写来创建自定义类型保护时,可以检查的内容没有限制 (若自定义类型保护被错误地编写,它会带来很多错误)

类型保护

instanceof 关键字

// 定义类
class Dog {
  wang = 'wangwang'
}
class Cat {
  miao = 'miaomiao'
}

// 定义函数
const getName = (animal: Dog | Cat) => {
  if (animal instanceof Dog) {
    return animal.wang
  } else if (animal instanceof Cat) {
    return animal.miao
  }
}

// 实例化创建类
const cat = new Cat();
const dog = new Dog();
// 调用函数
console.log(getName(cat)); // miaomiao
console.log(getName(dog)); // wangwang

typeof 关键字

function StudentId(x: string | number) {
  if (typeof x == 'string') {
    console.log('string');
  }
  if (typeof x === 'number') {
    console.log('number');
  }
}

StudentId(`446`); // Student
StudentId(446); // Id

in 关键字

// 定义对象类型
type Fish = {
  swim: () => void
}
type Bird = {
  fly: () => void
}
// 实现对象
let bird: Bird = {
  fly(): void { console.log('bird'); }
}
let fish: Fish = {
  swim(): void { console.log('fish'); }
}

function move(animal: Fish | Bird) {
  if ("swim" in animal) {
    animal.swim();
  } else {
    animal.fly();
  }

}
move(fish); // fish
move(bird); // bird

等式收缩式保护器

function getValues(a: number | string, b: string) {
  if (a === b) {
    console.log(typeof a); // 缩小到字符串 => string
  } else {
    console.log(typeof a); // 如果没有缩小,类型仍然未知
  }
}

带有谓词的自定义类型保护

TypeScript
TypeScript
// 1. 区分类型
interface Dog {
  eat: string;
  swim: string;
}
interface Cat {
  eat: string;
}
type Animal = Dog | Cat;

const isDog = (b: Animal): b is Dog => {
  return (b as Dog).swim !== undefined;
}

// 测试
const Dog: Animal = { eat: "骨头", swim: "游泳" };
const Cat: Animal = { eat: "鱼" };
console.log(isDog(Cat)); // false
console.log(isDog(Dog)); // true
// 2. API 响应验证
interface ApiSuccess<T> {
  status: "success";
  data: T;
  timestamp: Date;
}

interface ApiError {
  status: "error";
  error: string;
  code: number;
}

type ApiResponse<T> = ApiSuccess<T> | ApiError;

function isApiSuccess<T>(response: ApiResponse<T>): response is ApiSuccess<T> {
  return response.status === "success";
}

async function fetchData<T>(url: string): Promise<ApiResponse<T>> {
const response = await fetch(url);
  return await response.json();
}

async function getUserData() {
const response = await fetchData<{ name: string }>("/api/user");
  if (isApiSuccess(response)) {
    // response 是 ApiSuccess<{ name: string }>
    console.log(response.data.name);
  } else {
    // response 是 ApiError
    console.error(response.error);
  }
}
打赏作者
您的打赏是我前进的动力
微信
支付宝
评论

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

粽子

这有关于前端开发的技术文档和你分享。

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

了解更多

目录

  1. 1. 什么是类型保护
  2. 2. 类型保护
    1. 2.1. instanceof 关键字
    2. 2.2. typeof 关键字
    3. 2.3. in 关键字
    4. 2.4. 等式收缩式保护器
    5. 2.5. 带有谓词的自定义类型保护