Typescript with async and await: Variable is used before being assigned.ts(2454)

Viewed 2473

Why is typescript complaining here that variable is unassigned? Am I missing something obvious with scopes?

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 Answers

You are getting this error, because you have "strictNullChecks": true in your tsconfig.json. So the compiler shows you that the variable is possibly has value of undefined.

Options here are

  • to initialize the variable with a null-object instance (or empty values like "" for String, [] for Array, etc),
  • to use non-null assertion operator (
    expect(renderResult!.container.firstEleme... ),
  • disable the strictNullChecks in your tsconfig.json,
  • or any other way of checking for undefined or asserting the value to be not undefined.

But IMHO if you are using strictNullChecks, you should consider using null-object pattern.

Compiler complains because it is undefined and you do not check for it before using it. moreover, as been said, the compiler cannot know what happens inside the async functions, so it cannot know if it is assigned eventually.

you can just use expect(renderResult?.container?.firstElementChild!.getAttribute('src')).toBe('original');

so you will get 'false' if anything in that chain is undefined.

Another solution is to mark renderResult as RenderResult or undefined, and then accessing it with optional chaining at the end.

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');
});
Related