有没有一种简洁的方法可以因玩笑断言而缩小打字范围?

问题描述 投票:0回答:1

我在编写测试时遇到的一个烦人的问题如下所示:

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);

    // Despite already have asserted that isLoading is false,
    // Typescript isn't aware of it and
    // I still need to narrow the type by throwing an error
    if (result.isLoading) {
      throw new Error("expected isLoading to be false");
    }

    expect(result.data).toBe("hello world");
  });
});

有没有一种简洁的方法来避免这种不必要的错误抛出?

typescript jestjs
1个回答
0
投票

jest API 的实现方式并未充分利用 TypeScript 的功能。

您可以以对 TypeScript 更友好的方式编写测试,如下所示:

describe(getData, () => {
  it("behaves correctly", () => {
    const result = getData();
    if (result.isLoading) {
      expect(true).toBe(false);
    } else {
      expect(result.data).toBe("hello world");
    }
  });
});

或者像这样:

type Loading = { isLoading: true };
type NotLoading = { isLoading: false; data: string };
type Result = Loading | NotLoading;

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

function isNotLoading(result: Result): result is NotLoading {
  if (result.isLoading) {
      expect(true).toBe(false);
      return false;
  } else {
    return true;
  }
}

describe(getData, () => {
  it("behaves correctly", () => {
    const result = getData();
    if (isNotLoading(result)) {
      expect(result.data).toBe("hello world");
    }
  });
});
© www.soinside.com 2019 - 2024. All rights reserved.