Reputation: 57
I have a component called SelectField which is a wrapper that renders label, helper text and select input inside (inspired by TextField @material-UI).
SelectField exposes value
& onChange
props and forwards them to an internal select component.
It also exposes selectProps
prop which you can also use to pass props to the internal select:
// SelectField.tsx
type SelectFieldProps = {
...
selectProps?: SelectProps;
value?: SelectProps["value"];
onChange?: SelectProps["onChange"];
}
const SelectField = ({
value,
onChange,
selectProps
}: SelectFieldProps) => {
const props = {
value,
onChange,
...selectProps,
}
return (
<FormControl>
<Label>select</Label>
<select {...selectProps} />
</FormControl>
)
}
// Now the question part...
// App.tsx
// case 1
<SelectField
options={options}
selectProps={{
value,
// Line below works as expected, no typescript errors
onChange: (e) => setValue(e.target.value as string)
}}
/>
// case 2
<SelectField
options={options}
value={value}
// Line below gives following error:
// Property 'value' does not exist on type 'EventTarget | (EventTarget &
// HTMLInputElement) | (EventTarget & { value: unknown; name: string; })'.
// Property 'value' does not exist on type 'EventTarget'.ts(2339)
onChange={(e) => setValue(e.target.value as string)}
/>
Why does typescript complain about event.target not having "value" property in the second case, but not in the first?
From what I've understood in both cases event argument should have the same type, no?
Here is codesandbox example:
https://codesandbox.io/s/sad-shtern-xle91b?file=/src/App.tsx
Upvotes: 0
Views: 255
Reputation: 10662
Props
of SelectField
has & FormControlProps
which has its own onChange
type, so the final onChange
becomes a union type.
You can omit the unnecessary onChange
using Omit<FormControlProps, "onChange">
Upvotes: 2