Home > OS >  How to type React.useState() which can get multiple types as its value with Typescript
How to type React.useState() which can get multiple types as its value with Typescript

Time:12-02

I'm trying to type useState() hook which can get number and string type as its value.

export interface Select {
  selectValue: React.Dispatch<React.SetStateAction<number | string>>;
  ...
}

And I'm trying to use above component like this,

const [value, setValue] = React.useState(0);
<Select selectValue = {setValue} />

But It gives me this Error.

Type 'Dispatch<SetStateAction<number>>' is not assignable to type 'Dispatch<SetStateAction<string | number>>'.
  Type 'SetStateAction<string | number>' is not assignable to type 'SetStateAction<number>'.
    Type 'string' is not assignable to type 'SetStateAction<number>'.

How can I resolve this Error?

CodePudding user response:

You just need to provide a generic type argument to useState<T> like this:

const [value, setValue] = useState<string | number>(0);

Otherwise, it will infer the type from your initial value 0 which is only number. Here's a complete example:

TS Playground link

import {
  default as React,
  Dispatch,
  ReactElement,
  SetStateAction,
  useState,
} from 'react';

interface SelectProps {
  selectValue: string | number;
  setSelectValue: Dispatch<SetStateAction<string | number>>;
}

declare function Select (props: SelectProps): ReactElement;

function Example (): ReactElement {
  const [value, setValue] = useState<string | number>(0);
  return <Select selectValue={value} setSelectValue={setValue} />;
}

CodePudding user response:

Break it down so its like this:

export interface Select {
  selectValue: React.Dispatch<React.SetStateAction<number>> | React.Dispatch<React.SetStateAction<string>>;
  ...
}

Also why are you passing the setValue, did you mean to pass the value itself? (<Select selectValue = {value} />)

CodePudding user response:

You might need to check what the <Select> component's selectValue callback passes in the arguments. It might not be passing a number that is expected in the setValue method.

  • Related