TypeScript如何实现可返回值且具备类型断言能力的assert函数?
结论
TypeScript 目前的类型系统设计中,asserts 断言签名强制要求函数返回值为 void,无法和其他返回值类型组合使用,你最初的写法不符合当前语法规范。你自己实现的仅支持对象类型的版本是可行的方向,只需要调整泛型约束和返回值类型,就可以扩展到支持所有类型的校验。
可行实现方案
方案1:拆分两个函数(覆盖全部场景)
分别实现用于独立语句调用的断言函数,和用于嵌入表达式的真值收窄函数,二者搭配可以完全满足你的需求:
- 先定义真值类型别名:
// 定义所有假值类型 type Falsy = false | 0 | '' | null | undefined // 从泛型T中排除假值 type Truthy<T> = Exclude<T, Falsy>
- 独立调用用的断言函数:
function assert(condition: unknown, msg?: string): asserts condition { if (!condition) { throw new Error(msg) } }
- 嵌入表达式用的收窄函数:
function ensure<T>(condition: T, msg?: string): Truthy<T> { if (!condition) { throw new Error(msg) } return condition as Truthy<T> }
使用示例:
let success: boolean = true // 独立调用场景,会缩小当前作用域的success类型为true assert(success) // 嵌入表达式场景,直接返回收窄后的类型 const element: HTMLElement = ensure(document.getElementById('foo'))
方案2:单函数实现(仅支持表达式嵌入场景)
如果可以接受独立调用时不缩小当前作用域变量类型,仅用上述的ensure函数也能覆盖绝大多数嵌入表达式的使用场景,使用方式和你最初的设计完全一致。
内容的提问来源于stack exchange,提问作者Thomas
相关产品推荐
相关产品推荐

