Evangelos
Evangelos

Reputation: 47

Handling types when combining React HTML DOM events in a function call

Question: Is there a way to combine the types of different HTML DOM events in Typescript?

(I know I can avoid this error by splitting my function in two different functions but I want to avoid that)

My component looks similar to this:

const TestComponent: React.FC = () => {
const handleFileChange = (e: React.DragEvent | React.SyntheticEvent) => {
  const fileData = e.dataTransfer || e.target;
});

return (
  <div>
    <div onDrop={handleFileChange} />
    <input type="file" onChange={handleFileChange} />
  </div>
)};

The error I'm getting is on the e.dataTransfer inside the handleFileChange function:

Property 'dataTransfer' does not exist on type 'SyntheticEvent<Element, Event> | DragEvent<Element>'.
Property 'dataTransfer' does not exist on type 'SyntheticEvent<Element, Event>'.

I understand this error and why this is happening, but I can't find a workaround to do this with typescript, any docs reference I should be looking at?

Upvotes: 0

Views: 443

Answers (2)

Madhusudhan
Madhusudhan

Reputation: 101

You can try something like this.

const TestComponent: React.FC = () => {

  // you can use any value you want as `type`
  const handleFileChange = (type: "input" | "drop", e: React.DragEvent | React.SyntheticEvent) => {
    if (type === "drop") {
      const fileData = (e as React.DragEvent).dataTransfer
    }

    if (type === "input") {
      const target = e.target
    }

    // if there are any other events
  }

  return (
    <div>
      <div onDrop={handleFileChange.bind(null, "drop")} />
      <input type="file" onChange={handleFileChange.bind(null, "input")} />
    </div>
  )
}

Just bind a type to the event so with each event type you can decide what you want to do.

Upvotes: 1

Nicholas Tower
Nicholas Tower

Reputation: 84947

Your types are fine, you just need to check if dataTransfer exists before using it:

const handleFileChange = (e: React.DragEvent | React.SyntheticEvent) => {
  const fileData = 'dataTransfer' in e ? e.dataTransfer : e.target;
};

Upvotes: 1

Related Questions