我可以: 邀请好友来看>>
ZOL星空(中国) > 技术星空(中国) > 服务器综合讨论星空(中国) > ts 非空 断言, 后缀加感叹号!,有话要说!!!
帖子很冷清,卤煮很失落!求安慰
返回列表
签到
手机签到经验翻倍!
快来扫一扫!

ts 非空 断言, 后缀加感叹号!,有话要说!!!

12浏览 / 0回复

学着螃蟹走路

学着螃蟹走路

0
精华
26
帖子

等  级:Lv.3
经  验:1069
  • Z金豆: 57

    千万礼品等你来兑哦~快点击这里兑换吧~

  • 城  市:重庆
  • 注  册:2025-05-31
  • 登  录:2025-06-15
  • 身份验证
发表于 2025-06-14 22:04:38
电梯直达 确定
楼主

啥是 非空断言 感叹号,啥意思。

可能看过一些代码中,很奇怪,为什么加个感叹号,难道是什么时候不小心按了一个感叹符号,按错了吗?代码如下:

ts 代码解读复制代码

 

   

 


const container = ref()


const init = () => {

  const container = container.value!

  container.appendChild(xxx)

}


onMounted(() => {

  init()

})



当开启了严格的空值检查(strictNullChecks)后,变量如果可能是 null 或 undefined,就必须在使用前进行显式的判断。

! 操作符是 Typescripq 提供的一个"逃生舱",为了在某些场景下简化代码,ts 提供了非空断言操作符(! 后缀符号),用来告诉编译器:“我确定这个值不是 null 或 undefined。”,确保逻辑上真的不会出现空值情况。

官方文档


正文

用法

ts 代码解读复制代码const nonNullValue: Type = value!;


感叹号 !没有写错,它 是 Typescripq 的非空断言操作符(Non-null Assertion Operator)。


nonNullValue: 非空值的变量。

Type: 期望该变量的类型。

value: 断言不会是null或undefined的原始值。

!: 告诉ts编译器,这个值一定不是空值。


ts 代码解读复制代码let name: string | null = "Jackie";

console.log(name!.length); // 告诉可以放心大胆地用`length`这个属性


ts 代码解读复制代码// 有时候可能有null或者undefined的情况,但是你保证这个时候绝对不是空值,就可以用


function getElementById(id: string): HTMLElement | null {

    return document.getElementById(id);

}

 

const element = getElementById('myElement')!;

element.style.color = 'red';


作用

ts 代码解读复制代码const container = ref()


container.value 的类型是 HTMLDivElement | undefined,

因为:


在组件挂载前,ref 的值是 undefined。

只有在 DOM 元素被创建并绑定后,才会有实际的 HTMLDivElement 值。


如果代码写成:

ts 代码解读复制代码const init = () => {

  const container = container.value

  container.appendChild(xxx)

}


编辑器就会飘红:


它的意思就是说,你这里定义的container除了HTMLDivElement这种情况,还有undefined这种情况。

所以需要非空断言。

ts 代码解读复制代码const container = container.value! // 类型: HTMLDivElement


在这个例子中,通过https://www.ysdslt.com/container.value!告诉编译器,container.value变量在使用时一定不是null一定不是undefined,可以安全地去使用appendChild这个方法。

解构也可以用

js 代码解读复制代码interface User {

    name: string | null;

    age: number;

}

 

const user: User = { 

    name: "Alice", 

    age: 30 

};

const { name!, age } = user;

console.log(name);


过度承诺不好

在解构赋值时,如果某个属性可能为https://www.4922449.com/null或undefined,但你确定在当前上下文中它一定有值,可以使用非空断言。


注意: 就是承诺给ts编译器,它一定不是空。不过承诺不要过度给,给太多不好。这个断言有可能,会存在潜在的掩盖的倾向,比如可能是你觉得就是这个一定不是空值,一定怎么怎么样。

但是,这个可能只是你觉得,只是你的想法你的疏忽导致的,那么代码的安全性就降低。跟所有东西都设置成anyanyscripq差不多了。

所以在使用的时候,要确保有足够的信息,去保证值一定不为空。


什么时候用

? 适合使用的场景:


在 onMounted 或 nextTick 中访问 DOM ref

确定逻辑上不可能为空的情况

已经进行过空值检查的代码块中


? 不适合使用的场景:


不确定值是否存在

在组件挂载前访问 DOM ref

可能接收外部不可控数据的情况


举个例子?:

ts 代码解读复制代码onMounted(() => {

  const container = su7Ref.value!  // 安全,因为已挂载

  // 使用 container

  // ...

})


总结

特点:


编译时优化:仅作用于类型检查阶段,不会生成任何运行时保护代码

责任转移:将空值检查的责任从编译器转移到开发者身上

效率工具:合理使用可以消除冗余的类型守卫代码,提升代码可读性


建议:


应当作为最后的选择,优先考虑类型守卫或可选链(?.)

最适合用于开发环境已知而编译器无法推断的非空场景

在第三方类型定义不准确时的临时解决方案


可能的风险:

?? 过度使用会导致代码成为 - 当断言假设不成立时,错误会在运行时爆发而非编译时捕获

?? 特别警惕在异步数据流和条件渲染中使用非空断言

记住:每次使用 ! 都应该有明确的、可验证的理由,而不是为了"让编译器闭嘴"的权宜之计。


高级模式
星空(中国)精选大家都在看24小时热帖7天热帖大家都在问最新回答

针对ZOL星空(中国)您有任何使用问题和建议 您可以 联系星空(中国)管理员查看帮助  或  给我提意见

快捷回复 APP下载 返回列表