前端TS学习第五天

本文详细解释了JavaScript中的类型守卫,包括instanceof用于原型链检测,in用于属性判断,typeof用于类型检测,以及自定义守卫和类型断言的使用场景。同时提到了类型转换与类型断言的区别。
摘要由CSDN通过智能技术生成

类型守卫

为什么要用类型首位:
类型守卫定义:在语句的块级作用域【if语句内或条目运算符表达式内】缩小变量的一种类型推断的行为。
类型守卫产生时机:TS条件语句中遇到下列条件关键字时,会在语句的块级作用域内缩小变量的类型,这种类型推断的行为称作类型守卫(Type Guard)。类型守卫可以帮助我们在块级作用域中获得更为需要的精确变量类型。

  • 实例判断:instanceof

instanceof:测试prototype构造函数的属性是否出现在对象原型链中的任何位置

class Customer{
    pay(payMethod:BankPay|MobilePay){
        if(payMethod instanceof MobilePay){
            //payMethod
        }else if (payMethod instanceof BankPay){
            //payMethod
        }
    }
}
  • 属性或者方法判断:in

编译器可以自己检测出,包含属性的类型就是这个类型并且自动提示,且屏蔽掉另外一个,只要这个属性是一者有一者没有,就会自动定义到这个类型。

class MobilePay{
    appid:string

    constructor(props) {
        super(props);
        this.appid = appid
    }
}
class BankPay{

}
class Customer{
    pay(payMethod:BankPay|MobilePay){
       if("appid" in payMethod){
           payMethod.appid
       }
        // if(payMethod instanceof MobilePay){
        //     //payMethod
        // }else if (payMethod instanceof BankPay){
        //     //payMethod
        // }
    }
}
  • 类型判断:typeof
    在这里插入图片描述
    这个会报错是因为联合数据类型不能用作运算,所以这个时候typeof的作用就体现出来了
function cal(num:string|number){
    if(typeof num ==="number"){
        num+3;
    }//typeof会把范围直接缩小到number所以就可以进行运算了
}
  • 字面量相等判断:等,全等,不等,不全等

自定义守卫

在这里插入图片描述
如果判断为true,则是类型定义为 is之后的类型,如果是false就是另外一个类型。

class Customer{
    pay(payMethod:BankPay|MobilePay){
        if(isMobilePay(payMethod)){
            payMethod.
        }
    }

}

function isMobilePay(payMethod:Pay):payMethod is MobilePay{
    return payMethod instanceof MobilePay
}

typeof作用

typeof用来检测一个变量或者一个对象的数据类型

typeof检测的范围

typeof检测变量的类型范围包括:“string”|“number”|“bigint”|“boolean”|“symbol”|“undefined”|“object”|"function"等数据类型。

typeof的局限性(面试题!!!!)

如果你是直接打印,直接给你打印出object,这不能清晰的看到所属类型,所以这就是typeof的局限性,解决方法如下,自己看代码!!!!
在这里插入图片描述

console.log(arr);
console.log(set);
console.log(map);
const arr = [30,50]
console.log(typeof arr)
const set = new Set()
console.log(typeof set)
const map = new Map()
console.log(typeof map)

console.log(Object.prototype.toString.call(arr));
console.log(Object.prototype.toString.call(set));
console.log(Object.prototype.toString.call(map));

它也不是说所有的类型都可以检测出来,比如下面的例子

class Customer{
    custname
    buy(){}
}

console.log(Object.prototype.toString.call(Customer))
let cust = new Customer()
console.log(Object.prototype.toString.call(cust))
export {}

在这里插入图片描述

类型断言

语法格式:A 数据类型的变量 as B 数据类型
let b:B
let c:C=b as C
理解:是绕过TS编译检查,类型断言就是对编译器说:我就是这个类型了,无需检查
**类型断言的条件是:前后两者起码要有父子关系,要不然不能进行类型断言,一般是把父亲转化成子类的比较多

//举例就不写多了,随便搞点车放里面
export class Vechile{
    static count:number = 3
    public brand:string//品牌
    public vechileNo:string //车牌号
    public days:number //租赁天数
    public total:number = 0 //支付的租赁总费用
    constructor(brand_:string,vechileNo_:string,days_:number) {
        this.brand = brand_
        this.vechileNo = vechileNo_
        this.days = days_
    }

    public  calcualteRent(){
        console.log(this.brand+"车牌号为:"+this.vechileNo+"开始被租")
        return 0
    }
}

class Car extends Vechile{
    public type:string//车的型号
    constructor(brand_:string,vechileNo_:string,days_:number,type_:string) {
        super(brand_,vechileNo_,days_);
        this.type=type_
    }
    public getPriceByType(){
        let rentMoneyByDay:number = 0//每天的租金
        if(this.type=== "普拉多巡洋舰"){
            rentMoneyByDay = 800
        }else if(this.type==="凯美瑞旗舰版"){
            rentMoneyByDay = 400
        }else if(this.type==="威驰智行版"){
            rentMoneyByDay = 200
        }
        return rentMoneyByDay
    }
    public calcualteRend() {
        super.calcualteRent()
        console.log("小轿车租赁。。。")
        return this.days * this.getPriceByType()
    }
}

class Truck extends Vechile{
    ton!:number//座位数
    constructor(brand_:string,type_:string,days_:number,ton_:number) {
        super(brand_,type_,days_);
        this.ton = ton_
    }
    CalRentPrice(){
        let rentMoneyByDay:number=0//每天的租金
        if(this.ton<=500){
            rentMoneyByDay=750
        }else if(this.ton>500){
            rentMoneyByDay = 1350
        }
        return rentMoneyByDay
    }
    public calRent(){
        return this.CalRentPrice()*this.days
    }
}
class Customer{
    rent(vechile:Vechile){
        let car = vechile as Car

        car.calcualteRent();
    }
}

let cust:Customer=new Customer();
let vechile:Vechile=new Car("AA","一定",30,'普拉多巡洋舰');
vechile = new Truck("AA","一定",30,300)

export {}

类型断言使用场景

第一个场景在上面!!!!
第二个场景是如果在定义数据类型的时候,外部传入数据的问题,比如传入数据为string类型,那么会因为string类型的表达式不能用作索引类型,所以在引用时会出错,那么这个时候类型断言就非常有用了,看代码!!!!(除了string,symbol类型也不可以作索引,但是ts4.4版本之后,这个symbol好像作索引也不报错)

let symid = Symbol("userid")
let user = {[symid]:101,username:"wangwu",age:23}
let name1 = "username"
let userid = user[symid]
let username = user[username as any]//如果你这里直接写username,会报错
test({username:"wangwu",age:23})
function test(data:unknown){}
export {}

类型转换——编译器强制一个类型转换成另外一个类型。

类型转换和类型断言殊途同归,很像
比如
let a:A = < A > b

let car:Car = <Car>vechile
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值