Typescript React Dispatch

516 Views Asked by At
// MyComponent property
setSelected: Dispatch<SetStateAction<string>> | Dispatch<SetStateAction<string[]>>

// App.tsx
const [selected, setSelected] = useState<string[]>(['x'])

<MyComponent setSelected={setSelected} />

// MyComponent
setSelected(['x'])
// type error: Argument of type 'string[]' is not assignable to parameter of type 'SetStateAction<string> & SetStateAction<string[]>

I have a setSelected function. It will take string or string list and save it. But both of them give type error. What is the reason?

Also '|' as it appears in the error message indicates the '&' symbol as a symbol. I couldn't understand that either.

Another Type:

// MyComponent property
setSelected: Dispatch<SetStateAction<string | string[]>>

// App.tsx
const [selected, setSelected] = useState<string[]>(['x'])

<MyComponent setSelected={setSelected} />
// type error: Type 'Dispatch<SetStateAction<string[]>>' is not assignable to type 'Dispatch<SetStateAction<string | string[]>>
1

There are 1 best solutions below

6
Max On BEST ANSWER

When you define a union of functions, typescript resolves the argument as the intersection of of the function arguments.

For example (arg:string)=>{} | (arg:number)=>{} will be considered as (arg:string & number)=>{}.

React dispatch is defined as type Dispatch<A> = (value: A) => void; so it is a function.

SetStateAction is also possible a function, you can have callback version of setState.

So rather than

setSelected: Dispatch<SetStateAction<string>> | Dispatch<SetStateAction<string[]>>

you can use

setSelected: Dispatch<SetStateAction<string|string[]>>

So the union is applied to the generic which represents the arguments expected by setState.