你的类型守卫可能正在悄悄偏离 TypeScript 类型
来源:dev.to — 2026-09-23
📋 概述
作者指出一个看起来完全安全的类型守卫其实有漏洞:TypeScript 会相信你写的类型谓词,但它无法证明你的运行时检查真的校验了类型里的每一个字段。于是当 User 加了新字段而守卫忘了同步更新时,代码照样编译通过。手写守卫真正的麻烦不是写一次,而是长期保持两份定义同步:属性会被添加、删除、重命名、变为可选或换成另一种类型,而编译器可能什么都不说。他为此给 is-kit 加了 typedStruct,让守卫基于已有的应用类型构建,运行期照常做对象校验,编译期则检查守卫与它应当跟随的类型是否匹配——被遗忘的维护从运行时 bug 变成编译错误。
🔑 核心要点
- 根因是类型谓词是我们自己写的契约,而不是从函数体生成的证明——你只是在告诉编译器「相信我」。
- 一个糟糕透顶的守卫完全可以合法地通过 TypeScript 编译,因为它无法一般性地证明任意运行期逻辑校验了类型的每个部分。
- 漂移是维护问题:属性被加、删、改名、改可选或改类型时,某个运行期守卫可能要同步更新,而编译器不会提醒。
- typedStruct 不消除维护,它让被遗忘的维护变得可见:运行期 bug 直接变成编译期问题。
- optional 与 nullable 是两种不同的运行期契约:optionalKey 表示属性可能缺席,nullable 表示值可能是 null。
💡 金句
typedStruct 不消除维护,它只是让被遗忘的维护变得可见。
👍 0
👎 0
← 返回 dev.to 首页