【TypeScript】TS类型断言-类型的声明和转换(七)

文章介绍了TypeScript中断言的概念,包括尖括号形式和as形式的断言,用于在不确定类型时访问特定属性或方法。同时强调了断言可能导致运行时错误,应当谨慎使用。非空断言(!)用于确保变量不为null或undefined,肯定断言(变量名!)则表示变量将被赋值。文章还提到了将类型断言为any的情况以及在函数调用时对参数和返回值进行精确断言的重要性。
摘要由CSDN通过智能技术生成

前言

为什么要有断言这个概念?TS中并不能判断在使用联合类型时具体是那种类型?当我们不知道是什么类型的情况下要使用某个类型特有的属性或者方法,那么就可以用断言来实现,它实际上是对编辑器做了提前告知的行为,但是并不能保证运行中报错。主要有两种方式来实现,具体如下:

断言形式

(1)尖括号形式

语法:<type>+value,尖括号中填写具体的类型。

//anyValue是any类型,在使用时候将其断言为string类型
let anyValue:any = 'zhangsan';
let length:number = (<string>anyValue).length;//0 
//anyValue是string或者number联合类型,在使用时候将其断言为string类型
let anyValue:string | number = 'zhangsan';
let length:number = (<string>anyValue).length;//0 

使用断言虽然能避免编译中的报错,但是却避免不了运行中的报错

type ClaaM = number | string;
function func(val:ClaaM):string{ return(<string>val).substr(0,1)
}
func(1) 

我们可以看到编辑器中没有报错,如下: 在这里插入图片描述 但是编译成JS后,运行过程中就报错了,如下: 在这里插入图片描述 所以除非确切的知道变量的数据类型,否则不要使用类型断言,这是因为类型断言会让 TypeScript 编译器将变量当做指定的类型,而不管它实际的类型,在程序运行时可能有类型错误,断言需要慎用

(2)as形式(推荐)

语法:value as type,as后跟具体类型。

let anyValue:any = 'zhangsan';
let length:number = (anyValue as string).length;//0 

断言类型

(1)非空断言

含义:非空断言用!表示,它用来断定某变量一定不是 nullundefined。 如果不做非空判断则会直接报错,具体如下:

type ClassTime = () => number;
const start = (ClassTime: ClassTime | undefined | null)=> {let time = ClassTime(); 
} 

在这里插入图片描述

做了非空断言,则报错信息就没有了,函数在执行的时候会忽略undefined、null.

type ClassTime = () => number;
const start = (ClassTime: ClassTime | undefined | null) {let time = ClassTime!(); 
} 

这里出一个面试题,如下:

// 面试题 
const a: number | undefined = undefined;
const b: number = a!;//这里使用断言无效,a已经有明确的值
console.log(b); 
// 上面的代码会编译成
const a = undefined;
const b = a;
console.log(b); // undefined 

注意:只有在strictNullChecks开启时,TS才会报错,怎么开启呢?以VScode编辑器为例

  • 点击设置按钮后,选择设置选项 在这里插入图片描述
  • 搜索strictNullChecks,然后勾选下面的选项就可以啦 在这里插入图片描述

(2)肯定断言-肯定化保证赋值

含义:允许在实例属性或者变量声明后面放置一个 !号,从而告诉 TS该属性会被明确地赋值。 错误示范,我们在对变量赋值之前就使用变量,就会报错。

let score: number;
startClass();
console.log('' + score); // 使用前赋值
function startClass() {score = 5;
} 

编辑器中会直接报错,如图所示: 怎么避免这种现象呢?我们可以在变量声明的时候就告诉编辑器该属性一定会被赋值,即在变量名后面加个!符号

let score!: number;
startClass();
console.log('' + score); // 使用前赋值
function startClass() {score = 5;
} 

(3)将任何类型断言为any

为什么会有这种需求呢?比如以下案例:我们知道obj一定是有值的,请求接口后赋值给obj,所以一定是有值的,但是我们直接赋值,就会报错

const obj = {};
obj.name = 'zhangsan';
obj.age = 19; 

在这里插入图片描述 我们可以改成这样就不会报错啦

const obj:Object = {};
(<any>obj).name = 'zhangsan';
(<any>obj).age = 19; 

(4)调用函数时将参数和返回值断言成精确的值

 function func(val:any):any{return 1
}
func(1) 

调用函数时我们改成以下所示,这样方便我们维护代码,约束了传参和函数返回值,不能any走天下。

let data = <number>func(<string>'zhangsan') 

编译成JS如下

function func(val) {return 1;
}
var data = func('zhangsan'); 
any`走天下。
let data = <number>func(<string>'zhangsan') 

编译成JS如下

function func(val) {return 1;
}
var data = func('zhangsan'); 

最后

为大家准备了一个前端资料包。包含54本,2.57G的前端相关电子书,《前端面试宝典(附答案和解析)》,难点、重点知识视频教程(全套)。



有需要的小伙伴,可以点击下方卡片领取,无偿分享

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值