TypeScript能否实现兼具异步特性的类型断言函数?
TypeScript异步断言函数的实现方案
TypeScript不支持异步函数直接使用asserts precondition作为返回类型——因为异步函数必须返回全局Promise类型,而断言函数的类型收缩效果是同步生效的,无法直接适配异步场景。
要同时实现仅在断言失败时异步获取错误信息和让TypeScript识别断言后前置条件必定为true这两个需求,可以利用泛型条件类型结合控制流分析来实现:
async function myAssert<T extends boolean>( precondition: T, messageMaker: () => Promise<string | Error> ): Promise<T extends true ? void : never> { if (!precondition) { const message = await messageMaker(); throw message instanceof Error ? message : new Error(message); } }
代码说明
- 泛型约束:通过
T extends boolean将前置条件的类型绑定到泛型参数,让TypeScript跟踪其布尔值状态。 - 条件返回类型:
Promise<T extends true ? void : never>表示:- 当
precondition为true时,函数返回正常的Promise<void>; - 当
precondition为false时,函数返回Promise<never>——never类型意味着函数会抛出错误,不会正常完成。
- 当
- 错误处理:仅在
precondition为false时才调用异步的messageMaker获取错误信息,避免不必要的异步操作。
调用示例
// 调用后,TypeScript会自动推断response.ok为true await myAssert(response.ok, async () => await response.text()); // 此处可安全使用response,因为ok已被确认为true
这种写法利用TypeScript的控制流分析特性:如果await myAssert(...)之后代码继续执行,说明precondition必定为true(否则函数会抛出错误,代码不会走到这一步),从而自动完成类型收缩。
内容的提问来源于stack exchange,提问作者natevw
相关产品推荐
相关产品推荐

