select icon indicating copy to clipboard operation
select copied to clipboard

A typescript user should be able to specify the types for the options

Open dgreene1 opened this issue 4 years ago • 2 comments

Expected behavior:

I should be able to specify the strict option types as follows:

export const exampleComponent= () => {
    type SelectValues = 'jack' | 'lucy' | 'disabled' | 'Yiminghe';
    return (
        <div style={{ width: '250px' }}>
            <VtxSelect<SelectValues> size="middle" onChange={action('on-change')} defaultValue="jack">
                <VtxOption<SelectValues> value="jack">Jack</VtxOption>
                <VtxOption<SelectValues> value="lucy">Lucy</VtxOption>
                <VtxOption<SelectValues> value="disabled" disabled>
                    Disabled
                </VtxOption>
                <VtxOption<SelectValues> value="Yiminghe">yiminghe</VtxOption>
            </VtxSelect>
        </div>
    );
};

Actual Behavior:

I get the error Expected 0 type arguments, but got 1.ts(2558)

dgreene1 avatar Feb 11 '21 14:02 dgreene1

You can provide the value type already https://github.com/react-component/select/blob/master/src/Select.tsx#L73, but its unnecessary to define it on the Option.

chillyistkult avatar Feb 15 '21 17:02 chillyistkult

You can provide the value type already https://github.com/react-component/select/blob/master/src/Select.tsx#L73, but its unnecessary to define it on the Option.

@chillyistkult, allow me to explain that it is necessary to achieve full type safety. Can you spot the errors in the following code? Because after my PR (https://github.com/react-component/select/pull/596) is merged and after you explicitly add the type parameter for Select and Option, Typescript will catch at least two errors.

type SupportedColorNames = 'blue' | 'red' | 'green';

// This record is shown to help the use case for why strict typing for type literals is so important.
const supportedHexValues: Record<SupportedColorNames, string> = {
  blue: '#0000FF',
  green: '#00FF00',
  red: '#FF0000',
};

const ColorPicker = () => (
  <Select<SupportedColorNames>
    defaultValue="bright blue"
    onChange={value => {
      // this will throw VM106:1 Uncaught TypeError: Cannot read property 'toUpperCase' of undefined
      console.log(supportedHexValues[value].toUpperCase());
    }}
  >
    <Option<SupportedColorNames> value="blue">blue</Option>
    <Option<SupportedColorNames> value="red">red</Option>
    <Option<SupportedColorNames> value="grean">green</Option>
  </Select>
);

dgreene1 avatar Feb 15 '21 21:02 dgreene1