news 2026/10/14 19:15:55

TypeScript 04:类型断言与类型守卫

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
TypeScript 04:类型断言与类型守卫

TypeScript 04:类型断言与类型守卫

有 JS 基础即可阅读。建议先读第 01~03 课(本课大量用到第 02 课的「收窄」)。

1. 问题的起点:信息差

TS 只认代码里写出来的东西,而你经常「额外知道」一些它不知道的事(接口文档、页面结构、业务规则):

constraw='{"name":"Tom","age":18}'constparsed=JSON.parse(raw)// TS 的视角:什么都可能返回,不敢保证任何字段// 你的视角:看过文档,确定就是 { name: string; age: number }

TS 的原则是只认证据,不信口头保证。本课全部内容,就是「额外知识」交给它的几种方式。

2. as:签担保书

把你的知识硬塞给 TS:

constassured=JSON.parse(raw)as{name:string;age:number}// 读法:我看过数据了,它就是这个形状,你按这个来

两个本质:

  • 换标签,不换值——运行时什么都没做,值原封不动(只是改了快递箱上的标签,箱里东西没变)
  • 担保书 ≠ 验证器——TS 签收后不再核对,谎报了它不管:
constrisky=JSON.parse('{"name":"Tom"}')as{name:string;age:number}risky.age// ✅ 编译通过 → ❌ 运行时 undefined

两个类型毫无重叠时 TS 会拒绝担保:Conversion of type 'X' to type 'Y' may be a mistake(强行硬转要as unknown as T,等于放弃检查,慎用)。

3.!:快捷担保——只担保「非空」

constbtn=document.querySelector('.submit-btn')!// 我确定页面上一定有btn.addEventListener('click',onClick)

担保错了就是运行时TypeError。更稳的替代是给 TS 看证据:if (btn) { ... }。

4. is:把「证据」打包成函数

第 02 课的收窄(typeof/in)有效,是因为 TS亲眼看到了证据——但证据写在 if 里不可复用。is把证据装进函数,随处复用、收窄照常生效:

typeBird={fly:()=>string}typeFish={swim:()=>string}// 读法:函数返回 true 时,调用处的 pet 就是 FishfunctionisFish(pet:Bird|Fish):petisFish{return'swim'inpet// 函数体里还是那个证据}functionfeed(pet:Bird|Fish){if(isFish(pet)){returnpet.swim()// ✅ 收窄生效}returnpet.fly()// ✅ 剩余分支是 Bird}

关键对比——返回类型写成boolean链条就断了:

functionisFish(pet:Bird|Fish):boolean// ❌ TS 不知道 true 和 Fish 有什么关系functionisFish(pet:Bird|Fish):petisFish// ✅ true 就是证据

5. never 与穷尽检查:防盗警报

never= 没有任何值能是它(「不可能存在」)。推演一遍穷尽检查:

typeShape={kind:'circle';r:number}|{kind:'rect';w:number;h:number}functionarea(s:Shape):number{switch(s.kind){case'circle':returnMath.PI*s.r**2// 这里 s 收窄为 circle 分支case'rect':returns.w*s.h// 这里 s 收窄为 rect 分支default:const_alarm:never=s// 能掉进 default 的 s = 谁都没处理 = 空集 = neverreturn_alarm}}

这行能编译通过 = TS 替你确认了「全覆盖」。以后给Shape加{ kind: 'square' }却忘写 case:default 里的 s真的可能是 square(不再是空集),赋给never立刻报错——平时不响,一响必有贼(漏分支)。

6. satisfies:as 的改良版(初学可先跳过)

同样贴标签,但贴之前先验一遍形状,且不丢精确推断:

constconfig={home:{path:'/',title:'首页'},about:{path:'/about',title:'关于'},}satisfies Record<string,{path:string;title:string}>config.home.path// ✅ 精确类型还在,能补全// ❌ 某个 title 拼成 tittle → 立刻报错

配置表、路由表、常量表这类「结构要验、细节要留」的场景优先satisfies。

7. 断言 vs 守卫怎么选

手段语义用在哪
as/!我担保(TS 不再验证)边界处:第三方库缺类型、DOM 查询、已知结构的 JSON
is/ typeof / in先验证再用(证据)项目内部逻辑,默认选它
satisfies验证但保留精确推断配置 / 路由 / 常量表

原则:边界可以断言(守好门),内部优先收窄。断言用得越多,类型系统越像摆设。

8. 高频报错速查

报错人话
Conversion of type 'X' to type 'Y' may be a mistake两个类型没重叠,TS 拒绝瞎担保
Type 'Square' is not assignable to type 'never'穷尽检查触发:switch 漏了新分支
Object is possibly 'undefined'该收窄或!了
Property 'x' does not exist on type 'unknown'unknown 未收窄就想用
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/14 19:15:55

串口屏10家厂家横评:迪文、恒域威、大彩谁更值得买?

做设备的兄弟应该都懂&#xff0c;选串口屏这事看着简单&#xff0c;坑其实不少。样品阶段啥都好说&#xff0c;一到量产&#xff0c;交期、稳定性、售后全冒出来了。迪文、恒域威、大彩、欣瑞达、陶晶驰、鑫显、帝晶、尚视界、金玺、中显这10家我基本都摸过&#xff0c;今天用…

作者头像 李华
网站建设 2026/10/14 19:15:40

Gitee学习笔记

一、基本命令1. git init作用&#xff1a;在当前目录下初始化一个全新的空 Git 仓库&#xff0c;生成隐藏的 .git 文件夹。用法&#xff1a;git init执行完后&#xff0c;当前文件夹就从普通目录变成了 Git 可以管理的代码仓库&#xff0c;后续操作基于这个初始化环境。2. git …

作者头像 李华
网站建设 2026/10/14 19:12:42

C语言实现Renju五子棋AI:禁手判断与博弈搜索全攻略

简介&#xff1a;这份资源为C语言实现的Renju&#xff08;连珠&#xff09;规则五子棋AI&#xff0c;面向棋类AI开发者与算法学习者&#xff0c;完整示范了博弈树搜索与棋型评估的落地流程。包体十分精简&#xff0c;共3个C源文件、仅11KB&#xff0c;分别提供Linux运行版、Lin…

作者头像 李华
网站建设 2026/10/14 19:12:18

H-Trp-Asn-OH ;175027-11-9

基本性质英文名称&#xff1a;H-Trp-Asn-OH中文名称&#xff1a;色氨酰 - 天冬酰胺二肽CAS 号&#xff1a;175027-11-9类别&#xff1a;线性二肽分子式&#xff1a;C₁₅H₁₈N₄O₄分子量&#xff1a;318.33 Da等电点 pI&#xff1a;约 7.06溶解性&#xff1a;可溶于水、稀醋酸…

作者头像 李华
网站建设 2026/10/14 19:12:15

引擎基础系统与内存管理:从分层设计到分配器实战

1. 基础系统到底在“基础”什么很多人学引擎架构&#xff0c;一上来就看渲染、看物理、看动画&#xff0c;结果越看越晕。我在一线做引擎开发快十年&#xff0c;回过头来看&#xff0c;真正决定一个引擎好不好用的&#xff0c;不是那些炫酷的渲染特性&#xff0c;而是最容易被忽…

作者头像 李华
网站建设 2026/10/14 19:11:58

我为什么喜欢Go语言?

写代码期间用过VB、Delphi、C#、C、Ruby、Python&#xff0c;一直在寻找一门符合自己心意和理念的语言。我很在意写代码时的手感和执行的效率&#xff0c;所以在Go出现之前一直没有找到。在熟悉Go之后&#xff0c;我虽没有停下脚步&#xff0c;也去体验了D语言&#xff0c;但几…

作者头像 李华