La proprietà "valore" non esiste nel tipo EventTarget in TypeScript


118

Quindi il codice seguente è in Angular 4 e non riesco a capire perché non funziona come previsto.

Ecco uno snippet del mio gestore:

onUpdatingServerName(event: Event) {
  console.log(event);
  this.newserverName = event.target.value; //this wont work
}

Elemento HTML:

<input type="text" class="form-control" (input)="onUpdatingServerName($event)">

Il codice mi dà l'errore:

La proprietà "value" non esiste nel tipo "EventTarget".

Ma come si può vedere in console.logquel valore esiste suevent.target .


2
possiamo usare (e.target as HTMLInputElement) .value
user1162084

Risposte:


147

event.targetqui è un HTMLElementche è il genitore di tutti gli elementi HTML, ma non è garantito che abbia la proprietà value. TypeScript rileva questo e genera l'errore. Trasmetti event.targetall'elemento HTML appropriato per assicurarti HTMLInputElementche abbia una valueproprietà:

(<HTMLInputElement>event.target).value

Secondo la documentazione :

Digitare il $event

L'esempio sopra esegue il cast di $eventcome anytipo. Ciò semplifica il codice a un costo. Non ci sono informazioni sul tipo che potrebbero rivelare le proprietà dell'oggetto evento e prevenire errori stupidi.

[...]

L' $eventora è un preciso KeyboardEvent. Non tutti gli elementi hanno una valueproprietà, quindi esegue il cast targeta un elemento di input.

(Enfasi mia)


26
Sintassi un po 'più pulitavar element = ev.target as HTMLElement
Adrian Moisa

Per me, HTMLInputElement ha funzionato al posto di HTMLElement poiché HTMLElement non ha valore nell'interfaccia.
Harsha Vardhini

1
L'approccio migliore, a mio parere, è avere onFieldUpdate(event: { target: HTMLInputElement }) {nella funzione chiamata. Vedi la mia risposta di seguito.
belvederef

Per Angular 9 usa la sintassi "as". event.target as HtmlInputlement
Prescol

87

Anche il passaggio di HTMLInputElement come generico al tipo di evento dovrebbe funzionare:

onUpdatingServerName(event: React.ChangeEvent<HTMLInputElement>) {
  console.log(event);
  this.newserverName = event.target.value;
}

14
Questo è meglio delle asserzioni di tipo.
JamesYin

2
Questo non funzionerà se la funzione viene chiamata da, ad esempio, un onChangeriferimento al gestore di proprietà nel codice React. Il gestore di reazione non si aspetta che il tipo venga impostato per React.ChangeEvent e mostrerà un errore di digitazione. Ho dovuto ripristinare (una variante) risposta selezionata invece, con un cast: (event.target as HTMLInputElement).value.
Spiralis

Questo sembrava funzionare per me bene in un componente React. Forse è la versione di React? Siamo attualmente al 16.8. *.
hellatan

49

Ecco un'altra soluzione che funziona per me:

(event.target as HTMLInputElement).value

Questo dovrebbe eliminare l'errore facendo sapere a TS che event.targetè un HTMLInputElement, che ha intrinsecamente un value. Prima di specificare, TS probabilmente sapeva solo che eventda solo era un HTMLInputElement, quindi secondo TS il valore digitato targetera un valore mappato in modo casuale che poteva essere qualsiasi cosa.


4
Questo è stato davvero utile in React, dove ha cercato di interpretare <HTMLInputElement> come JSX.
Christopher Bradshaw

Hey amico, grazie per la condivisione! Questa soluzione si adatta a me.
Carlos Querioz

16

Stavo cercando una soluzione a un errore TypeScript simile con React:

La proprietà "dataset" non esiste nel tipo EventTarget in TypeScript

Volevo arrivare a event.target.datasetun elemento pulsante cliccato in React:

<button
  onClick={onClickHandler}
  data-index="4"
  data-name="Foo Bar"
>
  Delete Candidate
</button>

Ecco come sono riuscito a ottenere il datasetvalore "esistente" tramite TypeScript:

const onClickHandler = (event: React.MouseEvent<HTMLButtonElement>) => {
  const { name, index } = (event.target as HTMLButtonElement).dataset
  console.log({ name, index })
  // do stuff with name and index…
}

1
La domanda è contrassegnata come angolare, quindi una risposta React sembra fuori tema.
John Snow

2
Indipendentemente da ciò ... ha più voti positivi, quindi questa risposta è stata utile ad altri.
Beau Smith,

1
Funziona come un fascino. onChange={(event: ChangeEvent<HTMLInputElement>): void => { setTextFilter(event.target.value); }}
Vadorequest

3

Il modo in cui lo faccio è il seguente (meglio dell'asserzione del tipo imho):

onFieldUpdate(event: { target: HTMLInputElement }) {
  this.$emit('onFieldUpdate', event.target.value);
}

Ciò presuppone che tu sia interessato solo alla targetproprietà, che è il caso più comune. Se è necessario accedere alle altre proprietà di event, una soluzione più completa prevede l'utilizzo &dell'operatore di intersezione del tipo:

event: Event & { target: HTMLInputElement }

Questa è una versione di Vue.js ma il concetto si applica a tutti i framework. Ovviamente puoi andare più specifico e invece di usare un generale HTMLInputElementpuoi usare ad esempio HTMLTextAreaElementper le aree di testo.


2

Dovresti usare event.target.valueprop con il gestore onChange se non puoi vedere:

index.js:1437 Warning: Failed prop type: You provided a `value` prop to a form field without an `onChange` handler. This will render a read-only field. If the field should be mutable use `defaultValue`. Otherwise, set either `onChange` or `readOnly`.

Oppure, se vuoi usare un gestore diverso da onChange, usa event.currentTarget.value


questo funziona per me, ma non sono sicuro che l'utilizzo event.currentTarget.valuesia l'approccio migliore.
dczii
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.