reactjs - Typescript e React, diversi tipi tra tempo di compilazione e tempo di esecuzione per React.KeyboardEvent<HTMLInputElement>
TL;DR Object.getPrototypeOf(e.target) restituisce HTMLInputElement ma il compilatore dice che il tipo è EventTarget
Long: Ho un input semplice
<input
className="FilterInput"
type="text"
placeholder="Search for names..."
onKeyUp={filter}
/>
e una funzione per gestire il filtro
const filter = (e: React.KeyboardEvent<HTMLInputElement>) => {
console.log(Object.getPrototypeOf(e.target)) // prints "HTMLInputElement"
console.log((e.target as HTMLInputElement).value);
// ... other code
}
Sto cercando di capire meglio la teoria che sta dietro alla gestione dei tipi in Typescript, tuttavia non capisco perché devo usare i typehint
(e.target as HTMLInputElement).valuenel secondo console.log.
Se non lo faccio, il compilatore (tempo di compilazione) dice Property 'value' does not exist on type 'EventTarget'.. Quindi questo significa che al momento della compilazione il tipo di e.target è EventTarget.
Tuttavia, durante l'esecuzione testata con Object.getPrototypeOf(e.target), il tipo è HTMLInputElement (che ha la proprietà value).
Perché sta succedendo questo? È un errore nel mio codice, qualcosa legato a React o qualche parte della teoria della gestione dei tipi in Typescript che mi sto perdendo?
Inoltre, l'indicazione del tipo generico nella dichiarazione del parametro (e: React.KeyboardEvent<HTMLInputElement>) non dovrebbe essere sufficiente?
Grazie
Risposta n. 1
La risposta a questo è in realtà più legata a JS e alle API del DOM che a Typescript.
In breve, quello che vuoi davvero è event.currentTarget, poiché sarà l'elemento effettivo a cui hai collegato il listener.
event.target può essere qualsiasi elemento figlio del tuo elemento. Poiché può essere qualsiasi elemento, non può essere tipizzato in modo sicuro, quindi è tipizzato come il denominatore comune più basso, che è EventTarget. (ma devo dire che non sono sicuro del perché sia EventTarget e non Element)
Per ulteriori informazioni, vedi questa risposta: Qual è la differenza esatta tra la proprietà currentTarget e la proprietà target in JavaScript