You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何修复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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.02 19:54:02