reactjs - Hur man använder 2 typer av händelser i TypeScript-gränssnitt


Jag behöver skapa en anpassad REST-hook som har parametern Event, och denna parameter ska kunna ta emot 2 typer av händelser - tangentbord och mus. Jag försökte använda en union av typer som MouseEvent | KeyboardEvent och det fungerar inte :/

Några förslag? Exempel nedan

<input
  type="text"
  value={query}
  onChange={e => setQuery(e.target.value)}
  onKeyDown={e => getUserPosition(e, query, assetType)}
/>

<Button
  fullWidth
  color="secondary"
  onClick={e => getUserPosition(e, query, assetType)}
>
  Search
</Button>
const getUserPosition = (
    e: MouseEvent & KeyboardEvent, <-- here is problem
    queryuery: string,
    assetType: AssetType
  ) => {
    if (e?.key === 'Enter') {
      // do something
    }

    if (e?.type === 'click') {
      //do something
    }
  }

Svar #1

Detta är verkligen ett irriterande och konstigt drag från TypeScript. Först måste du använda typen MouseEvent | KeyboardEvent för händelsen eftersom den kommer från en onClick-callback ELLER en onKeyDown-callback.

Efter det måste du vara säker på vilken typ av händelse det är genom att kontrollera förekomsten av e.key till exempel

const getUserPosition = (e: MouseEvent | KeyboardEvent) => {
  if (e.key) {
    // it's a KeyboardEvent 
    if (e.key === "Enter") {
    // do something
    }
  } else {
    // it's a MouseEvent 
    if (e.type === "click") {
      //do something
    }
  }
};

Problemet då är att du fick detta fel:

Egenskapen 'key' finns inte på typen 'MouseEvent'

Du måste använda en giltig kontroll för att vara säker på att denna egenskap key finns i objektet e. Du kan använda för detta "key" in e:

const getUserPosition = (e: MouseEvent | KeyboardEvent) => {
  if ("key" in e) {
    // it's a KeyboardEvent 
    if (e.key === "Enter") {
    // do something
    }
  } else {
    // it's a MouseEvent 
    if (e.type === "click") {
      //do something
    }
  }
};

Svar #2

låt oss först titta på vad du har på funktionsdefinitionen...:

så du vill analysera en av två typer av händelser där en egenskap kan finnas på den ena men inte på den andra, så låt oss titta på detta första tillvägagångssätt...

/*
 * I Like your initial approach because it makes more logical sense this way,
 * only that you have to check if the property value you want to check is actually
 * in the value
 */
const getUserPosition = (e: MouseEvent | KeyboardEvent) => {
    if ('key' in e && e?.key === 'Enter') {
        // do something
    }

    if ('type' in e && e?.type === 'click') {
        //do something
    }
};

Relaterade artiklar