Właściwość „value” nie istnieje w typie EventTarget w TypeScript


119

Więc poniższy kod jest w Angular 4 i nie mogę zrozumieć, dlaczego nie działa tak, jak oczekiwano.

Oto fragment mojego programu obsługi:

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

Element HTML:

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

Kod daje mi błąd:

Właściwość „wartość” nie istnieje w typie „EventTarget”.

Ale jak widać w console.logtej wartości istnieje na event.target.


2
możemy użyć (e.target as HTMLInputElement) .value
user1162084

Odpowiedzi:


147

event.targettutaj jest, HTMLElementktóry jest rodzicem wszystkich elementów HTML, ale nie ma gwarancji, że będzie miał właściwość value. TypeScript wykrywa to i zgłasza błąd. Odlewanie event.targetdo odpowiedniego elementu HTML, aby zapewnić to HTMLInputElement, które ma valuewłaściwość:

(<HTMLInputElement>event.target).value

Zgodnie z dokumentacją :

Wpisz $event

Powyższy przykład rzuca $eventjako anytyp. To upraszcza kod kosztem. Nie ma informacji o typie, które mogłyby ujawnić właściwości obiektu zdarzenia i zapobiec głupim błędom.

[…]

$eventJest specyficzny KeyboardEvent. Nie wszystkie elementy mają valuewłaściwość, więc jest rzutowana targetna element wejściowy.

(Podkreślenie moje)


26
Nieco czystsza składniavar element = ev.target as HTMLElement
Adrian Moisa,

Dla mnie HTMLInputElement działał zamiast HTMLElement, ponieważ HTMLElement nie ma wartości w interfejsie.
Harsha Vardhini

1
Moim zdaniem najlepszym podejściem jest posiadanie onFieldUpdate(event: { target: HTMLInputElement }) {funkcji wywoływanej. Zobacz moją odpowiedź poniżej.
belvederef

W Angular 9 użyj składni „as”. event.target as HtmlInputlement
Prescol

88

Przekazywanie elementu HTMLInputElement jako generycznego do typu zdarzenia również powinno działać:

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

14
Jest to lepsze niż asercje typu.
JamesYin

2
To nie zadziała, jeśli funkcja jest wywoływana np. Z onChangeodwołania do obsługi proeperty w kodzie React. Procedura obsługi reakcji nie oczekuje, że typ zostanie ustawiony dla zdarzenia React.ChangeEvent i wyświetli błąd wpisywania. Musiałem wrócić do (wariantu) wybraną odpowiedź zamiast z obsadą: (event.target as HTMLInputElement).value.
Spiralis

Wydawało mi się, że działa to dobrze w komponencie React. Może to wersja Reacta? Jesteśmy obecnie na 16.8. *.
hellatan

49

Oto kolejna poprawka, która działa dla mnie:

(event.target as HTMLInputElement).value

Powinno to wyeliminować błąd, informując TS, że event.targetjest to HTMLInputElement, który z natury ma rozszerzenie value. Przed określeniem TS prawdopodobnie wiedział tylko, że eventsam był an HTMLInputElement, więc zgodnie z TS wpisana targetbyła jakaś losowo zmapowana wartość, która może być dowolną wartością.


4
Było to bardzo pomocne w Reakcie, gdzie próbował zinterpretować <HTMLInputElement> jako JSX.
Christopher Bradshaw

Hej stary, dzięki za udostępnienie! To rozwiązanie pasuje do mnie.
Carlos Querioz

16

Szukałem rozwiązania podobnego błędu TypeScript w React:

Właściwość „zestaw danych” nie istnieje w typie EventTarget w języku TypeScript

Chciałem dostać się do event.target.datasetelementu klikniętego przycisku w Reakcie:

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

Oto, w jaki sposób udało mi się uzyskać datasetwartość „istnieje” za pomocą języka 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
Pytanie jest oznaczone jako Angular, więc odpowiedź React wydaje się nie na temat.
John Snow

2
Mimo to… ma wiele głosów pozytywnych, więc ta odpowiedź była pomocna dla innych.
Beau Smith

1
Działa jak marzenie. onChange={(event: ChangeEvent<HTMLInputElement>): void => { setTextFilter(event.target.value); }}
Vadorequest

3

Sposób, w jaki to robię, jest następujący (lepszy niż asercja typu imho):

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

Zakłada się, że interesuje Cię tylko targetnieruchomość, co jest najczęstszym przypadkiem. Jeśli chcesz uzyskać dostęp do innych właściwości programu event, bardziej kompleksowe rozwiązanie obejmuje użycie &operatora przecięcia typu:

event: Event & { target: HTMLInputElement }

To jest wersja Vue.js, ale koncepcja dotyczy wszystkich frameworków. Oczywiście możesz pójść bardziej szczegółowo i zamiast używać generała HTMLInputElement, możesz użyć np. HTMLTextAreaElementDla obszarów tekstowych.


2

Powinieneś użyć event.target.valueprop z obsługą onChange, jeśli nie widzisz:

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`.

Lub jeśli chcesz użyć innej procedury obsługi niż onChange, użyj event.currentTarget.value


to działa dla mnie, ale nie jestem pewien, czy event.currentTarget.valuejest to najlepsze podejście.
dczii
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.