Властивість 'value' не існує для типу EventTarget у TypeScript


118

Отже, наступний код знаходиться у куті 4, і я не можу зрозуміти, чому він не працює так, як очікувалося.

Ось фрагмент мого обробника:

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

Елемент HTML:

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

Код дає мені помилку:

Властивість 'value' не існує для типу 'EventTarget'.

Але як видно з console.logцього значення, існує на event.target.


2
ми можемо використовувати (напр. ціль як HTMLInputElement) .value
user1162084

Відповіді:


147

event.targetОсь це HTMLElementбатьківський елемент усіх елементів HTML, але не має гарантії value. TypeScript виявляє це і видаляє помилку. Перейдіть event.targetдо відповідного елемента HTML, щоб переконатися, HTMLInputElementщо він має valueвластивість:

(<HTMLInputElement>event.target).value

Відповідно до документації :

Введіть $event

Приклад вище наведено $eventяк anyтип. Це спрощує код за вартістю. Немає інформації про тип, яка могла б виявити властивості об'єкта події та запобігти нерозумним помилкам.

[...]

$eventТепер специфічний KeyboardEvent. Не всі елементи мають valueвластивість, тому він targetпередає вхідний елемент.

(Наголос мій)


26
Трохи чистіший синтаксисvar element = ev.target as HTMLElement
Адріана Моїса

Для мене HTMLInputElement працював замість HTMLElement, оскільки HTMLElement не має значення в інтерфейсі.
Харша Вардіні

1
На мій погляд, найкращий підхід - onFieldUpdate(event: { target: HTMLInputElement }) {це функціонування, що називається. Дивіться мою відповідь нижче.
belvederef

Для кутових 9 використовуйте синтаксис "як". event.target as HtmlInputlement
Прескол

87

Передача HTMLInputElement як загального типу типу події також повинна працювати:

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

14
Це краще, ніж твердження типу.
JamesYin

2
Це не спрацює, якщо функція викликається, тобто onChangeпосиланням обробника власності у коді React. Обробник реакції не очікує встановлення типу для React.ChangeEvent, і покаже помилку введення тексту. Я повинен був повернутися до (варіант) обраного відповіді замість з кидком: (event.target as HTMLInputElement).value.
Спіраліс

Це, здавалося, добре спрацьовує в складі React. Можливо, це версія React? Зараз ми перебуваємо на 16.8. *.
Геллатан

49

Ось ще одне виправлення, яке працює для мене:

(event.target as HTMLInputElement).value

Це повинно позбутися помилки, повідомивши TS про те, що event.targetє an HTMLInputElement, що по суті має a value. Перш ніж вказувати, TS, ймовірно, лише знав, що eventпоодинці це було HTMLInputElement, тому, згідно з TS, введене в дію targetбуло деяким випадковим чином відображеним значенням, яке може бути чим завгодно.


4
Це було дуже корисно в React, де він намагався інтерпретувати <HTMLInputElement> як JSX.
Крістофер Бредшоу

Гей, дякую за частку! Це рішення мені підходить.
Карлос Кверіоз

16

Я шукав рішення для подібної помилки TypeScript з React:

Властивість "набір даних" не існує для типу EventTarget у TypeScript

Я хотів потрапити на event.target.datasetелемент, що натиснув кнопку в React:

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

Ось як я зміг отримати datasetзначення "існування" через 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
Питання позначено як кутове, тому відповідь Реагу здається поза темою.
Джон Сноу

2
Незалежно ... він має кілька голосів, тому ця відповідь була корисною для інших.
Бо Сміт

1
Працює як шарм. onChange={(event: ChangeEvent<HTMLInputElement>): void => { setTextFilter(event.target.value); }}
Vadorequest

3

Я це роблю так (краще, ніж твердження типу imho):

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

Це передбачає, що вас цікавить лише targetмайно, що є найпоширенішим випадком. Якщо вам потрібно отримати доступ до інших властивостей event, більш комплексне рішення передбачає використання &оператора перетину типів:

event: Event & { target: HTMLInputElement }

Це версія Vue.js, але ця концепція застосовується до всіх фреймворків. Очевидно, ви можете піти більш конкретно, а замість загального HTMLInputElementви можете використовувати, наприклад, HTMLTextAreaElementдля текстових звітів.


2

Ви повинні використовувати event.target.valueопору з обробником onChange, якщо ні, ви не бачили:

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

Або Якщо ви хочете використовувати інший обробник, ніж onChange, використовуйте event.currentTarget.value


це працює для мене, але я не впевнений, що event.currentTarget.valueце найкращий підхід.
dczii
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.