图片

●断言: 其实就是告诉 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 就会对每一个层级的数据进行最严格的判断和限制


陆荣涛
28 声望4 粉丝

千锋教育HTML5大前端教研总监