[react] Only allow thunks in useState when setting state that is a function (#36080)

* Only allow thunks for function state

* Add self to contributors list

* Fix bounds to be more precise, and split into multiple lines.

* Update index.d.ts
This commit is contained in:
Chris Sauvé
2019-06-19 19:39:07 -04:00
committed by Daniel Rosenwasser
parent ad587c5a6f
commit 598ffd0b99
2 changed files with 12 additions and 1 deletions

View File

@@ -21,6 +21,7 @@
// Saransh Kataria <https://github.com/saranshkataria>
// Kanitkorn Sujautra <https://github.com/lukyth>
// Sebastian Silbermann <https://github.com/eps1lon>
// Chris Sauve <https://github.com/lemonmade>
// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
// TypeScript Version: 2.8
@@ -804,7 +805,9 @@ declare namespace React {
// based on the code in https://github.com/facebook/react/pull/13968
// Unlike the class component setState, the updates are not allowed to be partial
type SetStateAction<S> = S | ((prevState: S) => S);
type SetStateAction<S> = S extends ((...args: any[]) => any) ?
(prevState: S) => S :
(S | ((prevState: S) => S));
// this technically does accept a second argument, but it's already under a deprecation warning
// and it's not even released so probably better to not define it.
type Dispatch<A> = (value: A) => void;

View File

@@ -201,6 +201,14 @@ function useEveryHook(ref: React.Ref<{ id: number }>|undefined): () => boolean {
// make sure the generic argument does reject actual potentially undefined inputs
// $ExpectError
React.useState<number>(undefined)[0];
// When state is a function type, it must be returned from a function,
// not provided directly.
// $ExpectError
React.useState<(() => boolean)>(() => true)[1](() => false);
// Returning a function for state is fine
React.useState<(() => boolean)>(() => true)[1](() => () => false);
// As is returning non-function members of a union
React.useState<(() => boolean) | number>(() => true)[1](() => 42);
// useReducer convenience overload