断言和类型守卫
断言
断言分为三种:类型断言、非空断言、确定赋值断言
当断言失效后,可能使用到:双重断言
类型断言
在特定的环境中,我们会比TS知道这个值具体是什么类型,不需要TS去判断,简单的理解就是,类型断言会告诉编译器,你不用给我进行检查,相信我,他就是这个类型
共有两种方式:
- 尖括号
- as(推荐)
ts
//尖括号
let num:any = '123'
let res1: number = (<string>num).length; // React中会 error
// 尖括号语法在React中会报错,原因是与JSX语法会产生冲突,所以只能使用as语法
// as 语法
let str: any = 'str';
let res: number = (str as string).length;
非空断言
在上下文中当类型检查器无法断定类型时,一个新的后缀表达式操作符 ! 可以用于断言操作对象是非 null 和非 undefined 类型。
示例:
ts
function func(username: string | null | undefined): void {
let uname: string = username // error
let uanme1: string = username! //
}
确定赋值断言
在TS 2.7版本中引入了确定赋值断言,即允许在实例属性和变量声明后面放置一个 ! 号,以告诉TS该属性会被明确赋值。
示例
ts
let username: string
let age!: number
console.log(username) // error
console.log(age) // ok
双重断言
双重断言用于处理当想将S类型的变量断言为T类型,但是S类型和T类型互相兼容的情况。
ts
type myType = string | number
const username = 'zs' as myType // ok
const username1 = 'zs' as string as myType // ok
type myType1 = {
a: string
b: number
}
const a = 'zs' as myType1 //error
const b = 'zs' as any as myType1 //ok
类型守卫
类型守卫:是可执行运行时检查的一种表达式,用于确保该类型在一定的范围内。
类型守卫就是你可以设置多种类型,但我默认你是什么类型的意思
目前,常有的类型守卫共有4种:in关键字、typeof关键字、instanceof和类型谓词(is)
in关键字
用于判断这个属性是那个里面的
ts
type myType1 = {
a: string
b: number
}
interface myType2 {
a1: number
b1: boolean
}
function func(data: myType1 | myType2) {
if ('a' in data) {
console.log('myType1')
}
if ('a1' in data) {
console.log('myType2')
}
}
func({ a1: 1, b1: true }) // myType2
func({ a: 'str', b1: 1 }) // myType1
typeof关键字
用于判断基本类型,如string | number等
示例:
ts
function func(data: string | number) {
if (typeof data === 'string') {
console.log('string')
}
if (typeof data == 'number') {
console.log('number')
}
}
func('123') // string
func(123) // number
instanceof关键字
用于判断一个对象是不是一个构造函数,或使用类的实例
示例
ts
class UserName {
name: string = 'zs'
}
class Age extends UserName {
age: number = 12
}
const setInfo = (data: UserName) => {
if (data instanceof Age) {
console.log(data.age)
} else {
console.log(data.name)
}
if (data instanceof UserName) {
console.log(data.name)
}
}
setInfo(new UserName()) // zs zs
setInfo(new Age()) // 12 zs
类型谓词
is 关键字一般用于函数返回值类型中,判断参数是否属于某一类型,并根据结果返回对应的布尔类型。
ts
function isString(s: any): s is string {
return typeof s === 'string'
}
// 判断参数是否为字符串,是在调用转大写方法
function ifUpperCase(str:unknown){
if(isString(str)){
str.toUpperCase()
// (parameter) str: string
}
}
s is string不仅返回boolean类型判断参数s是不是string类型, 同时明确的string类型返回到条件为true的代码块中.
因此当我们判断条件为true, 即str为string类型时, 代码块中str类型也转为更明确的string类型
类型谓词的主要特点是:
- 返回类型谓词,如 s is string;
- 包含可以准确确定给定变量类型的逻辑语句,如 typeof s === 'string'。