带有异步和等待的打字稿:在分配变量之前使用了变量.ts(2454)

时间:2020-04-03 19:52:56

标签: typescript react-testing-library

为什么打字稿在这里抱怨变量未分配?我错过了一些明显的范围吗?

test('test', async () => {
  let renderResult: RenderResult;
  await act(async () => {
    renderResult = render(<Component />);
  });

  await act(async () => {
    renderResult.rerender(<Component />);
  });
  // ERRROR: Variable 'renderResult' is used before being assigned.ts(2454)
  expect(renderResult.container.firstElementChild!.getAttribute('src')).toBe('original');
});

3 个答案:

答案 0 :(得分:1)

您收到此错误,因为您的 tsconfig.json 中有 "strictNullChecks": true。所以编译器会告诉你变量的值可能是 undefined。

这里的选项是

  • 使用 null-object 实例(或空值,如 "" 表示字符串,[] 表示数组等)初始化变量,
  • 使用 non-null assertion operator (
    expect(renderResult!.container.firstEleme... ),
  • 禁用 strictNullChecks 在您的 tsconfig.json 中,
  • 或任何其他方式 检查未定义或断言该值不是未定义的。

但是恕我直言,如果您使用的是 strictNullChecks,您应该考虑使用空对象模式。

答案 1 :(得分:0)

编译器抱怨,因为它是未定义的,因此您在使用它之前不会对其进行检查。而且,如上所述,编译器无法知道异步函数内部发生了什么,因此无法知道最终是否分配了它。

您可以只使用expect(renderResult?.container?.firstElementChild!.getAttribute('src')).toBe('original');

因此,如果该链中的任何内容未定义,您将得到'false'。

答案 2 :(得分:0)

另一种解决方案是将renderResult标记为RenderResult undefined,然后在末尾使用可选链访问它。

test('test', async () => {
  let renderResult: RenderResult | undefined
  await act(async () => {
    renderResult = render(<Component />);
  });

  await act(async () => {
    renderResult.rerender(<Component />);
  });
  // ERRROR: Variable 'renderResult' is used before being assigned.ts(2454)
  expect(renderResult?.container.firstElementChild!.getAttribute('src')).toBe('original');
});