TypeScript学习笔记之类型守卫

类型守卫

在 TypeScript中,类型守卫(Type Guards)是一种用于在运行时检查类型的机制。它们允许你在代码中执行特定的检查,以确定变量的类型,并在需要时执行相应的操作。

typeof 类型收缩

const isString = (str:any) => {
  return typeof str === 'string';
}
console.log(isString(11));  // false

在这个例子里面我们声明一个函数可以接受任意类型,只筛选出字符串类型,进行类型收缩。

instanceof

const isArr = (value:unknown) => {
    if(value instanceof Array){
        value.length
    }
}

使用 instanceof 类型守卫可以检查一个对象是否是特定类的实例

typeof 和 instanceof 是 TypeScript 中用于类型检查的两个不同的操作符,它们有不同的作用和使用场景。

const str = "Hello";
console.log(typeof str); // 输出: "string"

const num = 42;
console.log(typeof num); // 输出: "number"

const bool = true;
console.log(typeof bool); // 输出: "boolean"

注意事项:typeof 只能返回有限的字符串类型,包括 “string”、“number”、“boolean”、“symbol”、“undefined” 和 “object”。对于数组、null 等类型,typeof 也会返回 “object”。因此,typeof 对于复杂类型和自定义类型的判断是有限的。

instanceof
作用:instanceof 操作符用于检查一个对象是否是某个类的实例。它通过检查对象的原型链来确定对象是否由指定的类创建。

class Person {
  name: string;
  constructor(name: string) {
    this.name = name;
  }
}
const person = new Person("Alice");
console.log(person instanceof Person); // 输出: true
const obj = {};
console.log(obj instanceof Person); // 输出: false

注意事项:instanceof 操作符主要用于检查对象是否是特定类的实例,它无法检查基本类型。此外,它也无法检查对象是通过字面量创建的,因为字面量对象没有显式的构造函数。

自定义守卫

实现一个函数支持任意类型
如果是对象,就检查里面的属性,
如果里面的属性是number就取两位,如果是string就去除左右空格
如果是函数就执行

const isString = (val: any) => { return typeof val === 'string' }
const isNum = (val: any) => { return typeof val === 'number' }
const isFn = (val: any) => { return typeof val === 'function' }
const isObject = (val: any) => { return Object.prototype.toString.call(val) === '[object Object]' }

const f = (data: any) => {
  let value: any;
  if (isObject(data)) {
    Object.keys(data).forEach((val: any) => {
      value = data[val];
      if (isString(value)) {
        data[val] = value.trim();
      }
      if (isNum(value)) {
        data[val] = value.toFixed(2);
      }
      if (isFn(value)) {
        value();
      }
    });
  }
}
const obj={
  a:666.662,
  b:' test  ',
  c:function(){
    console.log(this);
    console.log(this.a);
  }
}
f(obj)

第一个问题:发现打印出的this执向windows,原因在于value是自身单独进行了调用,相当于局部函数,不是由obj所调用

修改:

const isString = (val: any) => { return typeof val === 'string' }
const isNum = (val: any) => { return typeof val === 'number' }
const isFn = (val: any) => { return typeof val === 'function' }
const isObject = (val: any) => { return Object.prototype.toString.call(val) === '[object Object]' }

const f = (data: any) => {
  let value: any;
  if (isObject(data)) {
    Object.keys(data).forEach((val: any) => {
      value = data[val];
      if (isString(value)) {
        data[val] = value.trim();
      }
      if (isNum(value)) {
        data[val] = value.toFixed(2);
      }
      if (isFn(value)) {
        data[val]();
      }
    });
  }
}
const obj={
  a:666.662,
  b:' test  ',
  c:function(){
    console.log(this);
    console.log(this.a);
  }
}
f(obj)

第二个问题:value.的时候没有代码提示

这时候就需要自定义守卫了

类型谓词的语法形式。它表示当 isString 返回 true 时,val 的类型被细化为 string 类型

const isString = (val: any): val is string => { return typeof val === 'string' }
const isNum = (val: any): val is number => { return typeof val === 'number' }
const isFn = (val: any) => { return typeof val === 'function' }
const isObject = (val: any) => { return Object.prototype.toString.call(val) === '[object Object]' }

const f = (data: any) => {
  let value: any;
  if (isObject(data)) {
    Object.keys(data).forEach((val: any) => {
      value = data[val];
      if (isString(value)) {
        data[val] = value.trim();
      }
      if (isNum(value)) {
        data[val] = value.toFixed(2);
      }
      if (isFn(value)) {
        data[val]();
      }
    });
  }
}
const obj = {
  a: 666.662,
  b: ' test  ',
  c: function () {
    console.log(this);
    console.log(this.a);
  }
}
f(obj)

自动提示就有了

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值