'react-select and typescript: Type 'string' is not assignable to type 'ValueType<OptionTypeBase>'

I am trying to create an example component that uses react-select with typescript.

For this, I created a functional component and added the default example from react-select docs:

const options = [
    {value: 'chocolate', label: 'Chocolate'},
    {value: 'strawberry', label: 'Strawberry'},
    {value: 'vanilla', label: 'Vanilla'},
];

const MyComponent = () => {

    const [selectedOption, setSelectedOption] = useState('chocolate');

    const handleChange = (option: string) => {
        setSelectedOption(option);
    };

    return (
        <Select
            value={selectedOption}
            onChange={(option) => handleChange(option)}
            options={options}
        />
    );

};

However, this gives me an error:

 Overload 1 of 2, '(props: Readonly<Pick<Props<OptionTypeBase>, string | number> & Props<OptionTypeBase> & Props<OptionTypeBase>>): StateManager<...>', gave the following error.
    Type 'string' is not assignable to type 'ValueType<OptionTypeBase>'.
  Overload 2 of 2, '(props: Pick<Props<OptionTypeBase>, string | number> & Props<OptionTypeBase> & Props<OptionTypeBase>, context?: any): StateManager<...>', gave the following error.
    Type 'string' is not assignable to type 'ValueType<OptionTypeBase>'.

what am I doing wrong?

My packages are:

    "@types/react": "^16.9.19",
    "@types/react-dom": "^16.9.5",
    "@types/react-select": "^3.0.10",
    "react": "^16.12.0",
    "react-dom": "^16.12.0",
    "react-select": "^3.0.8",
    "typescript": "^3.7.5"



Solution 1:[1]

You need to set a value from your options array as the current value of Select component.

This however is not the only problem because the type signature of the onChange function is somewhat confusing. You'll need to define a type for the options and use `ValueType´ in the onChange function signature.

Here's a working example

type OptionType = {
  value: string;
  label: string;
};

const options: OptionType[] = [
  { value: "chocolate", label: "Chocolate" },
  { value: "strawberry", label: "Strawberry" },
  { value: "vanilla", label: "Vanilla" }
];

const MyComponent = () => {
  const [selectedOption, setSelectedOption] = useState<ValueType<OptionType>>(options[0]);

  const handleChange = (option: ValueType<OptionType>) => {
    setSelectedOption(option);
  };

  return (
    <Select
      value={selectedOption}
      onChange={option => handleChange(option)}
      options={options}
    />
  );
};

More information about the issue https://github.com/JedWatson/react-select/issues/2902

Sandbox with the code above https://codesandbox.io/s/angry-frost-5bh1o

Solution 2:[2]

  <Select
    value={selectedOption}
    onChange={(option) => handleChange(option)}
    options={options}
  />

The issue is value must be an entry within options. You have set the state to the string "chocolate" and it's throwing an error indicating that isn't of the same type.

If you update your state to something like:

  const [selectedOption, setSelectedOption] = useState(options[0]);

It'll now work.

Solution 3:[3]

import AsyncSelect from 'react-select/async';  

interface ColourOption {
    readonly value: string;
    readonly label: string;
    readonly color: string;
    readonly isFixed?: boolean;
    readonly isDisabled?: boolean;
  }
  
  const colourOptions: readonly ColourOption[] = [
    { value: 'ocean', label: 'Ocean', color: '#00B8D9', isFixed: true },
    { value: 'blue', label: 'Blue', color: '#0052CC', isDisabled: true },
    { value: 'purple', label: 'Purple', color: '#5243AA' },
    { value: 'red', label: 'Red', color: '#FF5630', isFixed: true },
    { value: 'orange', label: 'Orange', color: '#FF8B00' }
  ];
  

  const filterColors = (inputValue: string) => {
    return colourOptions.filter((i) =>
      i.label.toLowerCase().includes(inputValue.toLowerCase())
    );
  };
  
  const promiseOptions = (inputValue: string) =>
    new Promise<ColourOption[]>((resolve) => {
      setTimeout(() => {
        resolve(filterColors(inputValue));
      }, 1000);
    });    


<AsyncSelect 
    isMulti
    cacheOptions
    defaultOptions
    placeholder ={"Start typing to add another conditions"}
    loadOptions={promiseOptions}
    />

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 brandfilt
Solution 2 user2340824
Solution 3 Mr. Sukhdev