一、什么是断言
- 断言:其实就是告诉 TS,我知道我自己在做什么,不要你管
- 因为我们在 TS 的开发过程中,TS 会识别我们写的所有的内容,然后会傻傻的根据代码去识别你写的内容
- 先来看个例子吧
const box = document.querySelector('.box')
console.log(box.innerHTML)
- 一段看似简单的代码,谁都认识
- 但是一旦运行起来
- 这是什么鬼,为什么会报错呢
- 浅浅的解释一下
- 我们通过 querySelector 方法从页面上获取一个元素
- 这是没有问题的,但是根据语法,我们获取到的有可能是一个元素
- 也有可能是 null,也就是页面上根本没有这个元素
- 但是 TS 在识别的时候,其实是傻傻的,不会去识别你的 html 元素,也不会去捕获你的页面
- 只是单纯的看你书写的 ts 代码,那么他就会认为,你有可能获取不到元素
- 这个时候,就会给你提示错误了
- 因为如果万一真的是 null,那么肯定是不能调用 innerHTML 属性的
- 错误也就出现了
- 当我们开发的时候,在写代码的时候,只要我们准确的告诉他,我这个代码一定能获取到元素,你不要管东管西的,那么 TS 就不会在提示错误了
- 就像上面的代码,只要你在使用 innerHTML 的时候,准确的告诉他
- 我的 box 一定是一个 HTML 元素,那么就一定能调用 innerHTML 这个属性
- 这个时候,TS 就不会给你提示错误了
二、类型断言
方式1: 利用 as 书写断言
- 语法 : 数据 as 类型
const box = document.querySelector('.box')
console.log((box as HTMLDivElement).innerHTML)
方式2 : 利用 <> 书写断言
- 语法 : <类型>数据
const box = document.querySelector('.box')
console.log((<HTMLDivElement>box).innerHTML)
- 这就是对一个数据进行类型断言
- 也就是在开发的过程中
- 讲某一个数据断定为某一个类型
- 这样就可以直接按照该数据类型去调用属性和方法了
三、非空断言
- 也就是在开发的过程中,忽略有可能出现的 undefined 和 null 类型
- 这里我们使用 ! 来做这个事情
const box = document.querySelector('.box')
console.log(box!.innerHTML)
- 注意
- 当 box 只有可能是 一个内容 或者 undefined 或者 null 的时候
- 我们可以用 ! 进行断言,也就是告诉他,box 不可能是 null 或者 undefined
- 利用 ! 排除了 undefined 和 null 的可能
四、确定赋值断言
- 在开发中还有这样一种情况,就是我们在初始定义某一个变量的时候,有可能是不赋值的
- 在后面的代码或者函数内对其进行赋值,然后再使用
// 初始化的时候不进行赋值
let n: number
// 通过调用这个函数对 n 进行赋值操作
function init () { n = 100 }
init()
// 这里使用一下 x
console.log(x.toFixed(2))
- 然后我们就发现,TS 又提示错误了
- 这是因为 TS 不太清楚你的 init 函数调用以后会对 x 进行赋值
- 所以就会告诉你,你还没有赋值呢,就调用了 toFixed 方法
- 这个时候,我们就可以使用确定赋值断言,还是使用 !
// 初始化的时候不进行赋值
let n!: number
// 通过调用这个函数对 n 进行赋值操作
function init () { n = 100 }
init()
// 这里使用一下 x
console.log(x.toFixed(2))
- 在初始化的时候,给变量后面加一个 !
- 也就是告诉 TS,这个变量我一定会百分之一万赋值的,你少管
- 这样今后在遇到你使用 x 这个变量的时候
- TS 就会默认认为他一定有值
- 也就不会提示错误了
五、const 断言
- 这个有点和我们定义变量的关键字差不多,但是又不太一样,小伙伴不要搞混淆了哦
- 我们先来看这个代码把
let n: number = 100 as const
let s: string = 'hello world' as const
- 这样一来,我们定义的 n 和 s 就不能被更改了
- 我直接用 const 定义变量不好吗,为什么 … ( 如果不能骂街,那我无话可说 )
- hold on … hold on !!
- 我们再来看下一段代码
const obj = { name: 'Jack', age: 18 }
- 这个就是用 const 定义的一个变量,只不过值是一个引用数据类型了
- 我们的 const 只能保证 obj 不会被改变,但是 obj 内部的子级数据是不会被限制的
- 如果我们想让 obj 内的每一个成员都是只读的属性,不允许被更改呢
- 只能是在书写接口的时候,把每一个属性都定义为 readonly
- O(∩_∩)O哈哈~,我的 const 断言有用武之地了
const obj = { name: 'Jack', age: 18 } as const
- 这样一来,我们 obj 内 所有的子级数据就都不能被更改了
- 注意:
- const:是 ES6 中定义变量的关键字,反应当前定义的是一个常量,不允许被更改,但是对于引用数据类型来说,起子属性还是可以被修改的
- as const:TS 内的语法,告诉 TS,被断言的内容不管是自己本身还是其子属性都不允许被修改,TS 就会对每一个层级的数据进行最严格的判断和限制