facebook / react

The library for web and native user interfaces.
https://react.dev
MIT License
228.61k stars 46.8k forks source link

Bug: React + Typescript - useReducer's initializer arg is required even though it shouldn't be #27052

Closed JorensM closed 6 months ago

JorensM commented 1 year ago

When using the useReducer() hook in Typescript, it complains that the hook call is missing the initializer function argument, even though according to React docs this argument is optional.

React version:

Steps To Reproduce

  1. In a React + Typescript project
  2. Call the reducer hook in a functional component
  3. See linter warning

Code example:

const [ state, dispatch ] = useReducer<string[], () => {}>(() => {}, []);

Error message:

Expected 3 arguments, but got 2. An argument for 'initializer' was not provided.

The current behavior

Linter gives warning about missing argument

The expected behavior

Linter shouldn't give a warning as this argument is optional.

TolgaYigit commented 1 year ago

It appears that there is an issue with the type definitions. If we examine line 953 of the react/index.d.ts file in the DefinitelyTyped repository (https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/react/index.d.ts), we can observe that the initializer argument is not optional. Curiously, on line 969, the initializer is marked as optional, even though both definitions share the same description: "overload where dispatch could accept 0 arguments."

See: https://github.com/DefinitelyTyped/DefinitelyTyped/pull/47322

github-actions[bot] commented 6 months ago

This issue has been automatically marked as stale. If this issue is still affecting you, please leave any comment (for example, "bump"), and we'll keep it open. We are sorry that we haven't been able to prioritize it yet. If you have any new additional information, please include it with your comment!

JorensM commented 6 months ago

I'll make a PR on the DefiniteltyTyped repo when I have some free time.

@TolgaYigit it seems that the PR you mentioned was closed, though I'm not sure why

eps1lon commented 6 months ago

useReducer<string[], () => {}>(() => {}, []) will be the supported typing pattern in React 19. In React 18, you have to wrap the type parameters in React.Reducer like so: useReducer<React.Reducer<string[], () => {}>>(() => {}, []);