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

如何通过Jest断言优雅实现TypeScript类型收窄?

问题描述

在编写TypeScript+Jest测试时遇到类型收窄问题:已通过Jest断言result.isLoading为false,但TypeScript无法识别该断言结果,仍需手动通过抛错收窄类型,想找更简洁的替代方式。

代码示例:

function getData(): { isLoading: true } | { isLoading: false; data: string } {
  return {
    isLoading: false,
    data: "hello world",
  };
}

describe(getData, () => {
  it("behaves correctly", () => {
    const result = getData();

    expect(result.isLoading).toBe(false);

    // 尽管已经断言isLoading为false,TypeScript仍不识别,需手动抛错收窄类型
    if (result.isLoading) {
      throw new Error("expected isLoading to be false");
    }

    expect(result.data).toBe("hello world");
  });
});
解决方案

以下几种简洁方式可避免手动抛错的冗余代码:

1. 类型断言配合expect.assertions()

直接用类型断言告诉TypeScript当前result的具体类型,同时用expect.assertions()确保前置断言已执行,避免类型断言的风险:

describe(getData, () => {
  it("behaves correctly", () => {
    const result = getData();
    expect.assertions(2); // 保证两个断言都会执行
    expect(result.isLoading).toBe(false);
    
    // 类型断言收窄后直接访问data属性
    expect((result as { isLoading: false; data: string }).data).toBe("hello world");
  });
});

2. 封装带断言的类型守卫

写一个自定义类型守卫,把Jest断言逻辑封装进去,一次调用同时完成测试验证和类型收窄:

function isLoaded(result: ReturnType<typeof getData>): result is { isLoading: false; data: string } {
  expect(result.isLoading).toBe(false);
  return !result.isLoading;
}

describe(getData, () => {
  it("behaves correctly", () => {
    const result = getData();
    
    if (isLoaded(result)) {
      // 此处TypeScript已自动识别result的类型
      expect(result.data).toBe("hello world");
    }
  });
});

这种方式逻辑复用性强,后续其他测试用例也能直接调用该类型守卫。

3. 使用Jest属性断言辅助类型推断

用expect(result).toHaveProperty('isLoading', false)代替普通的布尔断言,部分场景下TypeScript能基于这个断言自动收窄类型:

describe(getData, () => {
  it("behaves correctly", () => {
    const result = getData();
    
    expect(result).toHaveProperty('isLoading', false);
    // 此时TypeScript可识别result.isLoading为false,能直接访问data
    expect(result.data).toBe("hello world");
  });
});

注意:这种方式的类型推断依赖TypeScript对Jest断言的类型支持,稳定性略逊于前两种方法。

内容的提问来源于stack exchange,提问作者dwjohnston

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 12:41:03