TypeScript 中的 ! 和 ? 操作符

在 TypeScript 中,! 和 ? 是两个非常重要且常用的操作符,分别用于非空断言可选链操作。下面简单介绍一下二者。

1. 非空断言操作符 !

1.1 含义

非空断言操作符 !(Non-null assertion operator)用来告诉 TypeScript 编译器,某个值在当前情况下绝对不是 null 或 undefined,即使 TypeScript 的类型系统无法推断这一点。这会绕过 TypeScript 的类型检查,直接断言该值不是 null 或 undefined。

🌰

let user = {name: 'Alice',age: 25
};// TypeScript 会认为 user.address 可能是 undefined,因为它没有在 user 对象中定义// 使用非空断言,告诉 TypeScript 我确信 user.address 存在,可以强制将其视为有效的对象。
console.log(user.address!.length);

这里,user.address! 告诉 TS user.address 一定有值,因此可以安全地调用 .length。 如果 user.address 真的为 undefined,就会抛出运行时错误。

const singleRef = ref();const open = () => {singleRef.value!.openDialog();
};

这里 ! 告诉 TS,尽管 singleRef.value 可能是 null 或 undefined,但确定在调用 openDialog 时一定是有值的,因此跳过类型检查。

1.2 适用场景

- 当确信某个值不会是 null 或 undefined,并且 TypeScript 编译器无法推断出这一点时,可以使用 ! 告知 TS 该值运行时肯定存在。

- 在某些情况下,可能是外部库的 API 或代码中的某些逻辑导致 TS 无法推断出某个值的类型,可以使用 ! 强制该值不是 null 或 undefined。

1.3 注意事项

1)过度使用 ! 会让 TypeScript 类型系统失去意义,这可能会在运行时导致错误。因为强行告诉 TypeScript 这个值不会是 null 或 undefined,但实际上可能是,这会导致潜在的运行时错误。

2)谨慎使用,只有在非常确定值不会为 null 或 undefined 的情况下使用。

2. 可选链操作符 ?

2.1 含义

可选链操作符 ?(Optional chaining operator)允许我们安全地访问一个对象的属性或方法,而不必担心中间某一环节为 null 或 undefined。如果对象的某个部分为 null 或 undefined,则表达式会短路并返回 undefined,而不会抛出错误。

🌰

const user = {name: 'Alice',address: {city: 'New York'}
};// 使用可选链操作符安全访问
console.log(user.address?.city); // "New York"// 连续链式调用
const length = user.address?.street?.length; // undefined,而不是抛出错误
console.log(length); // undefined

这里,user.address?.city 可以安全地访问 address 属性,即使 user.address 为 undefined,也不会抛出错误,而是返回 undefined。

const singleRef = ref();const open = () => {singleRef.value?.openDialog();
};

这里 ? 表示如果 singleRef.value 是 null 或 undefined,则不调用 openDialog 方法,而是返回 undefined,避免抛出错误。

2.2 适用场景

- 当访问对象的深层嵌套属性时, 不确定某个中间属性是否存在,使用 ? 可以防止因访问 null 或 undefined 的属性而导致的错误。

- 当调用一个方法或访问一个属性时,可能该对象本身或某些属性可能为 null 或 undefined,可选链操作符帮助我们避免报错。

2.3 注意事项

1)可选链操作符可以防止错误,但它不会提供默认值,如果需要返回一个默认值,可以结合 ??(空值合并操作符)使用。

2)如果属性链中的任何一部分为 null 或 undefined,则后续的属性访问停止,结果为 undefined,而不会抛出异常。如果该属性存在,继续访问链式属性。这能避免代码中因访问未定义属性而导致的运行时错误,尤其是在处理不确定或动态结构的数据时非常有用。

3. 总结 ! 和 ? 

3.1 作用不同

- ! 是非空断言,告诉 TypeScript 确定某个值不为空,可以绕过类型检查,但其本身不处理 null 或 undefined 的问题。

- ? 是可选链操作符,用于安全地访问对象属性或方法,避免抛出错误,自动处理 null 或 undefined 的情况。

3.2 使用场景

- ! 适用于非常确定某个值不为 null 或 undefined 的场景,是一种强制断言,要求开发者对代码有明确的信心保证。

- ? 适用于不确定某个值是否存在,想要安全访问嵌套属性或方法的场景。

3.3 性能考虑

- 使用 ! 时,TypeScript 会跳过类型检查,但在运行时仍然可能抛出异常,因此它不提供运行时安全性。

- 使用 ? 时,TypeScript 会在运行时检查值是否为 null 或 undefined,并返回 undefined,避免报错。

这两个操作符在书写 TypeScript 代码时都非常有用,可以帮助我们写出更健壮的代码。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/16275.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

js中typeOf无法区分数组对象

[TOC](js中typeOf无法区分数组对象) 前提:很多时候我们在JS中用typeOf来判断值类型,如:typeOf ‘abc’//string ,typeOf 123 //number; 但当判断对象为数组时返回的仍是’object’ 这时候我们可以使用Object.prototype.toString.c…

【时间之外】IT人求职和创业应知【36】-肖申克的救赎

目录 新闻一:信息技术应用创新产业大会在深圳开幕 新闻二:人工智能与大数据融合应用成为创业新热点 新闻三:云计算与边缘计算协同发展推动IT行业创新 认知和思考决定了你的赚钱能力。以下是今天可能引起你思考的热点新闻: 新闻…

STL之vecor的使用(超详解)

目录 1. C/C中的数组 1.1. C语言中的数组 1.2. C中的数组 2. vector的接口 2.1. vector的迭代器 2.2. vector的初始化与销毁 2.3. vector的容量操作 2.4. vector的访问操作 2.5. vector的修改操作 💓 博客主页:C-SDN花园GGbond ⏩ 文章专栏…

Python异常处理day8

1、异常处理机制 1.1内置异常 常见的内置异常,修改元组,输出变量为被定义,强转错误,将字符串转成整型,索引超范围,除数不能为0,引用未被定义的模组,字符串与整型加减,各…

FFmpeg 4.3 音视频-多路H265监控录放C++开发十三.2:avpacket中包含多个 NALU如何解析头部分析

前提: 注意的是:我们这里是从avframe转换成avpacket 后,从avpacket中查看NALU。 在实际开发中,我们有可能是从摄像头中拿到 RGB 或者 PCM,然后将pcm打包成avframe,然后将avframe转换成avpacket&#xff0…

软件测试之缺陷编写

软件测试之缺陷编写 1. 缺陷报告示例2. 缺陷的跟踪流程3. 提交缺陷注意事项 1. 缺陷报告示例 2. 缺陷的跟踪流程 发现bug后怎么办? 要确认bug的可复现. 3. 提交缺陷注意事项

建筑工程内部知识库:提升项目管理效率的关键

在建筑工程领域,项目管理的效率直接关系到项目的成本、进度和质量。随着信息技术的快速发展,内部知识库已成为提升项目管理效率的关键工具。本文将探讨如何通过内部知识库优化建筑工程项目管理,并提供一些实用的策略和建议。 一、内部知识库…

Vue前端开发之组件事件

在一个组件中,不仅可以定义属性,还能定义事件,同时,在定义的事件中,还可以传递事件参数,校验参数,组件中定义的事件,可以被调用此组件的父级组件监听,当触发子级组件的事…

Springboot 整合 Java DL4J 打造金融风险评估系统

🧑 博主简介:CSDN博客专家,历代文学网(PC端可以访问:https://literature.sinhy.com/#/literature?__c1000,移动端可微信小程序搜索“历代文学”)总架构师,15年工作经验,…

【Unity】ScriptableObject的应用:利用配方合成新物体

前一篇已经使用ScriptableObject(SO)类配置可放置物体,本篇探索更多的SO类应用场景。 需求分析 将若干指定物体放在工作台上,可以生成新的物体。 成果展示 Scene部分 准备工作台,放在工作台上的物体全部放在指定PlacedObjects空物体下。 …

实践1:创建 POST、GET、DELETE 请求

好的,以下是关于HTTP请求的详细内容: 一、HTTP请求 HTTP(HyperText Transfer Protocol)是用于在Web浏览器和服务器之间传输数据的协议。它是Web的基础,也是RESTful API通信的核心。HTTP请求由客户端(如浏…

每日小题--买股票的最佳时机

目录 题目 分析 解题思路 完整代码 题目 给定一个数组 prices ,它的第 i 个元素 prices[i] 表示一支给定股票第 i 天的价格。 你只能选择 某一天 买入这只股票,并选择在 未来的某一个不同的日子 卖出该股票。设计一个算法来计算你所能获取的最大利润…

企业一站式管理系统odoo的研究——PLM插件的搭建

大纲 1. 环境准备1.1 安装操作系统1.2 更新操作系统1.3 配置用户组和用户1.3.1 创建用户组 odoo1.3.2. 创建用户 odoo1.3.3. 设置用户 odoo 的密码1.3.4. 验证用户和组1.3.5. 将用户 odoo 添加到添加sudo组:1.3.6. 切到odoo用户 2. 安装 Odoo1. 安装依赖项目2.2. 安…

泰矽微重磅发布超高集成度车规触控芯片TCAE10

市场背景 智能按键和智能表面作为汽车智能化的重要部分,目前正处于快速发展阶段,电容式触摸按键凭借其操作便利性与小体积的优势,在汽车内饰表面的应用越来越广泛。对于空调控制面板、档位控制器、座椅扶手、门饰板、车顶控制器等多路开关的…

10月回顾 | Apache SeaTunnel社区动态与进展一览

各位热爱 Apache SeaTunnel 的小伙伴们,社区10月份月报来啦,请查收! 这里将记录Apache SeaTunne社区每月动态和进展,欢迎关注。 月度Merge之星 感谢以下小伙伴上个月为 Apache SeaTunnel 所做的精彩贡献(排名不分先…

__VUE_PROD_HYDRATION_MISMATCH_DETAILS__ is not explicitly defined

VUE_PROD_HYDRATION_MISMATCH_DETAILS 未明确定义。您正在运行 Vue 的 esm-bundler 构建,它期望这些编译时功能标志通过捆绑器配置全局注入,以便在生产捆绑包中获得更好的tree-shaking优化。 Vue.js应用程序正在使用ESM(ECMAScript模块&#…

浪潮信息“源”Embedding模型登顶MTEB榜单第一名

在自然语言处理(NLP)和机器学习领域,Embedding模型是将文本数据转换为高维向量表示的核心技术,直接影响NLP任务(如文本分类、情感分析等)的效果,对于提升模型性能和深入理解文本语义具有至关重要…

一文6个步骤带你实现接口测试入门

软件测试资料领取:[内部资源] 想拿年薪40W的软件测试人员,这份资料必须领取~ 软件测试面试刷题工具:软件测试面试刷题【800道面试题答案免费刷】 一、接口测试概述 1 什么是接口测试: 接口测试是测试系统组件间交互的一种测试…

成人失禁护理领导品牌可靠亮相广州SIC老博会 助力推动养老产业高质量发展

2024年11月15日至17日,第十届中国国际老龄产业博览会(SIC老博会)在广州保利世贸博览馆开幕。可靠股份(股票代码:301009)携成人失禁护理系列等经典及战略产品受邀亮相本次展会,全方位展示企业在产…

【macOS】Mac安装consola字体至系统和PyCharm的最简单教程

博主本人是Mac小白,刚使用Air没多久,今天coding的时候发现PyCharm的字体怎么看怎么不舒服,一对比才发现跟win里的有较大差别,查看Mac的PyCharm字体原来是默认的JetBrains Mono: 但由于PyCharm可以同步账号的所有设置再…