如何基于type-fest的IsEqual实现TypeScript类型相等断言工具?
类型相等断言工具函数的实现问题
我用TypeScript开发,依赖type-fest包做文档验证,需要断言两个类型是否相等。原本的写法是:
const b: IsEqual<{a: 1}, {a: 1}> = true; console.log(b);
当传入的类型不相等时,TypeScript会在第一行报错,第二行是为了消除“变量未使用”的TS错误。
现在想封装成更简洁的工具函数:
function type_fest_is_equal_assertion<T, S>(): void { let R: IsEqual<T, S> = true; // 此处编译报错 console.log(R); } // 期望调用方式 type_fest_is_equal_assertion<{a: number}, {a: number}>()
但标记行出现编译错误:
Type 'boolean' is not assignable to type 'IsEqual<T, S>'.
错误原因澄清
IsEqual<T, S>的返回类型并非boolean,而是一个类型级别的布尔值(即true或false字面量类型)。当直接把运行时的true赋值给类型为IsEqual<T, S>的变量时,TypeScript无法确定IsEqual<T, S>是否等于true字面量,因此报错。
解决方案
方案1:通过泛型约束限制合法调用
import type { IsEqual } from 'type-fest'; function type_fest_is_equal_assertion<T, S extends T extends infer U ? (IsEqual<U, S> extends true ? U : never) : never>(): void { const R = true as IsEqual<T, S>; console.log(R); } // 合法调用:类型相等,无报错 type_fest_is_equal_assertion<{a: number}, {a: number}>(); // 非法调用:类型不等,编译报错 type_fest_is_equal_assertion<{a: number}, {a: string}>();
方案2:简化版,利用条件类型触发报错
import type { IsEqual } from 'type-fest'; function type_fest_is_equal_assertion<T, S>(): void { // 仅当IsEqual<T,S>为false时触发类型错误 const _: IsEqual<T, S> extends true ? true : never = true; console.log(true); }
当IsEqual<T,S>为false时,_的类型会变成never,true无法赋值给never,从而触发编译报错,达到断言效果。
方案3:非函数式的简洁断言写法
如果不需要函数形式,也可以用类型别名加变量声明简化:
import type { IsEqual } from 'type-fest'; type AssertEqual<T, S> = IsEqual<T, S> extends true ? true : never; // 断言类型相等,无报错 const _: AssertEqual<{a: number}, {a: number}> = true; // 类型不等时编译报错 const __: AssertEqual<{a: number}, {a: string}> = true;
内容的提问来源于stack exchange,提问作者Marcus Junius Brutus
相关产品推荐
相关产品推荐

