如何修复Jest中类型收束失效的expectNotInstanceOf断言函数
问题根源
你原先的expectNotInstanceOf类型定义里直接使用了typeof obj,这里的obj是函数入参声明的unknown类型,Exclude<typeof obj, E>等价于Exclude<unknown, E>,最终计算结果还是unknown,完全无法继承调用侧传入的实际类型,也就做不到类型收束。
修复方案
给函数新增一个泛型参数T用来承接调用侧传入的obj实际类型,基于T做类型排除即可:
// 新增泛型T承接obj的输入类型 export function expectNotInstanceOf<T, E, A extends unknown[]>( obj: T, type: new (...args: A) => E ): asserts obj is Exclude<T, E> { expect(obj).not.toBeInstanceOf(type); }
修正后调用expectNotInstanceOf(obj, Foo)时,TypeScript会自动推导T为Foo | Bar,Exclude<Foo | Bar, Foo>计算结果就是Bar,后续访问obj.bar()就不会再抛出类型错误。
完整可运行代码示例
export function expectInstanceOf<E, A extends unknown[]>(obj: unknown, type: new (...args: A) => E): asserts obj is E { expect(obj).toBeInstanceOf(type); } // 修正后的反向断言函数 export function expectNotInstanceOf<T, E, A extends unknown[]>(obj: T, type: new (...args: A) => E): asserts obj is Exclude<T, E> { expect(obj).not.toBeInstanceOf(type); } class Foo { foo() { /**/ } } class Bar { bar() { /**/ } } function foo(obj: Foo | Bar) { expectInstanceOf(obj, Foo); obj.foo(); // 类型正常收束为Foo } function notFoo(obj: Foo | Bar) { expectNotInstanceOf(obj, Foo); obj.bar(); // 类型正常收束为Bar,无类型错误 }
内容的提问来源于stack exchange,提问作者user3612643
相关产品推荐
相关产品推荐

