能否编写抛出异常而非返回布尔值的类型守卫?并重构相关代码?
能否编写抛出异常而非返回布尔值的类型守卫?
当然可以!这种函数在TypeScript里叫做断言函数(Assertion Functions),从3.7版本开始就支持了,完美解决你现在重复写判断+抛错的冗余问题。
直接看重构后的代码:
// 定义断言函数,明确告知TS:执行完没抛错的话,d一定是Data类型 function assertData(d: Data | null): asserts d is Data { if (d === null) { throw new Error("Invalid data"); } } class C { data: Data | null; public doA() { assertData(this.data); // 这里TypeScript会自动把this.data的类型缩小为Data,不用再手动判断 /* 后续可以直接安全操作this.data */ } public doB() { assertData(this.data); /* 同理,这里也能直接使用Data类型的this.data */ } }
关键细节说明:
- 断言函数的返回类型用
asserts d is Data,这是TypeScript专门为这类函数设计的语法——它告诉编译器:只要这个函数正常执行完毕(没有抛出异常),那么参数d的类型就一定是Data。 - 这样你就把重复的“判断+抛错”逻辑完全封装到了
assertData里,所有需要校验的地方直接调用这个函数就行,代码更简洁也更易维护。
额外小技巧:
如果你的场景不止校验Data | null,而是需要通用的“排除null/undefined”的断言,还可以写一个更通用的版本:
function assertIsDefined<T>(value: T): asserts value is NonNullable<T> { if (value === null || value === undefined) { throw new Error(`Expected value to be defined, but got ${value}`); } }
这个函数可以复用在任何需要确保值不是null或undefined的场景里,比如assertIsDefined(this.data)、assertIsDefined(someOtherValue)等,非常灵活。
最后要注意:断言函数必须在不满足条件时抛出异常,否则TypeScript会提示语法错误——毕竟它的核心作用就是通过抛错来保证后续代码的类型安全性。
内容的提问来源于stack exchange,提问作者Clément
相关产品推荐
相关产品推荐

