So instead of using Select directly I thought it would be better to create a component named CustomSelect which will return Select with some properties prefilled.
The issue is that now when I use the CustomSelect component with property isMulti={false}
typescript does not automatically understands that OnChange property should be of type
(newValue: SingleValue<IOption>, actionMeta: ActionMeta<IOption>) => void
instead of
(newValue: SingleValue<IOption> | MultiValue<IOption>, actionMeta: ActionMeta<IOption>) => void
Why is this happening and is there any good workaround?
CustomSelect.tsx
import Select, {
components,
OptionProps,
ValueContainerProps,
Props as SelectProps,
} from "react-select";
import { IOption } from "../../Table/Types";
import "./CustomSelect.scss";
//type IOption = {
// value: any;
// label: string;
// icon?: string;
//};
const { Option: OptionCointainer, ValueContainer } = components;
function OptionWithIcon(props: OptionProps<IOption>) {
const {
label,
data: { icon },
} = props;
return (
<OptionCointainer {...props} className="selectOption">
{!!icon && <img src={icon} alt={label} />}
{label}
</OptionCointainer>
);
}
// react-select is buggy when you try to override rendered value component
// children is being used as a workaround
function ValueWithIcon(props: ValueContainerProps<IOption>) {
const { getValue, children } = props;
const { label, icon } = getValue()[0];
return (
<ValueContainer {...props} className="selectValue">
<>
{!!icon && <img src={icon} alt={label} />}
{label}
<span className="hiddenAbsolute">{children}</span>
</>
</ValueContainer>
);
}
function CustomSelect(props: SelectProps<IOption>) {
const { options } = props;
return (
<Select
isDisabled={options ? options.length < 2 : true}
components={{
Option: OptionWithIcon,
ValueContainer: ValueWithIcon,
}}
{...props}
/>
);
}
export default CustomSelect;
Filters.tsx
<Select
id="currencyFrom"
isMulti={false}
value={state.fromCurrency}
// if I hover on change type is (newValue: SingleValue<IOption>, actionMeta: ActionMeta<IOption>) => void
onChange={onValueChange("fromCurrency")}
options={someOptions}
isSearchable={false}
/>
<CustomSelect
id="currencyTo"
isMulti={false}
value={state.toCurrency}
// if I hover on change type is (newValue: SingleValue<IOption> | MultiValue<IOption>, actionMeta: ActionMeta<IOption>) => void
onChange={onValueChange("toCurrency")}
options={someOptions}
isSearchable={false}
/>