Properti 'nilai' tidak ada pada tipe EventTarget di TypeScript

118

Jadi kode berikut ada di Angular 4 dan saya tidak tahu mengapa itu tidak berfungsi seperti yang diharapkan.

Berikut ini cuplikan dari handler saya:

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

Elemen HTML:

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

Kode memberi saya kesalahan:

Properti 'nilai' tidak ada pada jenis 'EventTarget'.

Tapi seperti yang bisa dilihat pada nilai console.logitu memang ada di event.target.

Ravy
sumber
2
kita dapat menggunakan (e.target as HTMLInputElement] .value
user1162084

Jawaban:

147

event.targetdi sini adalah HTMLElementyang merupakan induk dari semua elemen HTML, tetapi tidak dijamin memiliki properti value. TypeScript mendeteksi ini dan melempar kesalahan. Transmisikan event.targetke elemen HTML yang sesuai untuk memastikan HTMLInputElementyang memang memiliki valueproperti:

(<HTMLInputElement>event.target).value

Sesuai dokumentasi :

Ketik $event

Contoh di atas menampilkan $eventsebagai anytipe. Itu menyederhanakan kode dengan biaya tertentu. Tidak ada jenis informasi yang dapat mengungkapkan properti objek acara dan mencegah kesalahan konyol.

[...]

The $eventsekarang spesifik KeyboardEvent. Tidak semua elemen memiliki valueproperti, jadi ini mentransmisikan targetke elemen masukan.

(Penekanan saya)

Andrew Li
sumber
26
Sintaks yang sedikit lebih bersihvar element = ev.target as HTMLElement
Adrian Moisa
Bagi saya, HTMLInputElement berfungsi sebagai ganti HTMLElement karena HTMLElement tidak memiliki nilai dalam antarmuka.
Harsha Vardhini
1
Pendekatan terbaik, menurut saya, adalah memiliki onFieldUpdate(event: { target: HTMLInputElement }) {fungsi yang dipanggil. Lihat jawaban saya di bawah.
belvederef
Untuk Angular 9 gunakan "sebagai" sintaks. event.target as HtmlInputlement
Prescol
87

Meneruskan HTMLInputElement sebagai generik ke jenis acara juga harus berfungsi:

onUpdatingServerName(event: React.ChangeEvent<HTMLInputElement>) {
  console.log(event);
  this.newserverName = event.target.value;
}
Mikael Lirbank
sumber
14
Ini lebih baik daripada pernyataan tipe.
JamesYin
2
Ini tidak akan berfungsi jika fungsi dipanggil dari yaitu onChangereferensi penangan proeperty dalam kode React. Penangan react tidak mengharapkan tipe yang akan disetel untuk React.ChangeEvent dan akan menampilkan kesalahan pengetikan. Aku harus kembali ke (varian) jawaban yang dipilih sebagai gantinya, dengan gips: (event.target as HTMLInputElement).value.
Spiralis
Ini sepertinya bekerja dengan baik untuk saya dalam komponen React. Mungkin ini versi React? Kami saat ini berada di 16.8. *.
hellatan
49

Berikut perbaikan lain yang berhasil untuk saya:

(event.target as HTMLInputElement).value

Itu harus menghilangkan kesalahan dengan memberi tahu TS bahwa itu event.targetadalah HTMLInputElement, yang secara inheren memiliki value. Sebelum menentukan, TS mungkin hanya tahu bahwa eventsaja itu adalah HTMLInputElement, jadi menurut TS yang dimasukkan targetadalah beberapa nilai yang dipetakan secara acak yang bisa berupa apa saja.

Matt S.
sumber
4
Ini sangat membantu di React yang mencoba menafsirkan <HTMLInputElement> sebagai JSX.
Christopher Bradshaw
Halo, terima kasih telah berbagi! Solusi ini cocok untuk saya.
Carlos Querioz
16

Saya sedang mencari solusi untuk kesalahan TypeScript serupa dengan React:

Properti 'dataset' tidak ada pada tipe EventTarget di TypeScript

Saya ingin event.target.datasetmembuka elemen tombol yang diklik di React:

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

Berikut adalah bagaimana saya bisa mendapatkan datasetnilai untuk "ada" melalui 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…
}
Beau Smith
sumber
1
Pertanyaan ditandai sebagai Angular sehingga jawaban React sepertinya keluar dari topik.
John Snow
2
Terlepas dari ... itu memiliki banyak suara, jadi jawaban ini telah membantu orang lain.
Beau Smith
1
Bekerja seperti pesona. onChange={(event: ChangeEvent<HTMLInputElement>): void => { setTextFilter(event.target.value); }}
Vadorequest
3

Cara saya melakukannya adalah sebagai berikut (lebih baik daripada tipe pernyataan imho):

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

Ini mengasumsikan Anda hanya tertarik pada targetproperti, yang merupakan kasus paling umum. Jika Anda perlu mengakses properti lain dari event, solusi yang lebih komprehensif melibatkan penggunaan &operator persimpangan tipe:

event: Event & { target: HTMLInputElement }

Ini adalah versi Vue.js tetapi konsepnya berlaku untuk semua kerangka kerja. Jelas Anda bisa lebih spesifik dan daripada menggunakan umum HTMLInputElementAnda bisa menggunakan misalnya HTMLTextAreaElementuntuk textareas.

belvederef
sumber
2

Anda harus menggunakan event.target.valueprop dengan onChange handler jika tidak, Anda dapat melihat:

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

Atau Jika Anda ingin menggunakan handler selain onChange, gunakan event.currentTarget.value

JillAndMe
sumber
ini berfungsi untuk saya tetapi saya tidak yakin menggunakan event.currentTarget.valueadalah pendekatan terbaik.
dczii