如何将TypeScript断言条件封装为便捷的通用断言函数?
实现TypeScript通用类型断言函数
可以编写一个基于泛型的通用断言函数,满足assertType(entity, [Types.a, Types.b])的调用形式,同时保留原有的类型缩小效果:
enum Types { a = "a", b = "b", c = "c" } type Entity = { type: Types }; // 通用类型断言函数 function assertType<T extends Entity, U extends T['type']>( entity: T, allowedTypes: readonly U[] ): asserts entity is T & { type: U } { if (!allowedTypes.includes(entity.type as U)) { throw new Error(`无效的实体类型,允许的类型为: ${allowedTypes.join(', ')}`); } } // 调用示例 function abc(entity: Entity) { assertType(entity, [Types.a, Types.b]); // 此时 entity.type 被推断为 Types.a | Types.b } function def(entity: Entity) { assertType(entity, [Types.b, Types.c]); // 此时 entity.type 被推断为 Types.b | Types.c } function ghi(entity: Entity) { assertType(entity, [Types.c]); // 此时 entity.type 被推断为 Types.c }
核心要点说明
- 泛型约束:
T extends Entity确保传入的参数符合实体结构,U extends T['type']提取并约束允许的类型集合为原type类型的子集 - 断言语法:
asserts entity is T & { type: U }告诉TypeScript,断言成功后实体的type属性会被缩小为指定的允许类型集合 - 运行时检查:通过
includes判断实体类型是否在允许列表中,不符合则抛出错误 - 类型推断优化:使用
readonly U[]让TypeScript能正确推断数组元素的联合类型,无需额外手动指定泛型参数
这个函数完全替代原有断言逻辑,调用更简洁,同时保持相同的类型检查效果。
内容的提问来源于stack exchange,提问作者NtsDK
相关产品推荐
相关产品推荐

