wolfdale
wolfdale

Reputation: 57

Typescript complains about e: EventTarget not having "value" property in onChange function if I pass it as forwarded prop through wrapper component

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

Answers (1)

Ramesh Reddy
Ramesh Reddy

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">

Edit affectionate-sky-88xj13

Upvotes: 2

Related Questions