Properti 'nilai' tidak ada pada jenis 'EventTarget'


115

Saya menggunakan TypeScript Versi 2 untuk kode komponen Angular 2.

Saya mendapatkan error "Properti 'nilai' tidak ada pada jenis 'EventTarget'" untuk kode di bawah ini, apa solusinya. Terima kasih!

e.target.value.match (/ \ S + / g) || []).panjangnya

import { Component, EventEmitter, Output } from '@angular/core';

@Component({
selector: 'text-editor',
template: `
<textarea (keyup)="emitWordCount($event)"></textarea>
 `
 })
  export class TextEditorComponent {
   @Output() countUpdate = new EventEmitter<number>();

emitWordCount(e: Event) {
    this.countUpdate.emit(
        (e.target.value.match(/\S+/g) || []).length);
}
}

Jawaban:


189

Anda perlu memberi tahu TypeScript secara eksplisit jenis HTMLElement yang merupakan target Anda.

Cara melakukannya adalah menggunakan tipe generik untuk mentransmisikannya ke tipe yang tepat:

this.countUpdate.emit((<HTMLTextAreaElement>e.target).value./*...*/)

atau (sesuka Anda)

this.countUpdate.emit((e.target as HTMLTextAreaElement).value./*...*/)

atau (sekali lagi, masalah preferensi)

const target = e.target as HTMLTextAreaElement;

this.countUpdate.emit(target.value./*...*/)

Ini akan memberi tahu TypeScript bahwa elemennya adalah a textareadan akan mengetahui properti nilai.

Hal yang sama dapat dilakukan dengan semua jenis elemen HTML, setiap kali Anda memberikan TypeScript sedikit lebih banyak informasi tentang jenisnya, Anda akan terbalas dengan petunjuk yang tepat dan tentu saja lebih sedikit kesalahan.

Untuk mempermudah masa depan, Anda mungkin ingin menentukan acara secara langsung dengan jenis targetnya:

// create a new type HTMLElementEvent that has a target of type you pass
// type T must be a HTMLElement (e.g. HTMLTextAreaElement extends HTMLElement)
type HTMLElementEvent<T extends HTMLElement> = Event & {
  target: T; 
  // probably you might want to add the currentTarget as well
  // currentTarget: T;
}

// use it instead of Event
let e: HTMLElementEvent<HTMLTextAreaElement>;

console.log(e.target.value);

// or in the context of the given example
emitWordCount(e: HTMLElementEvent<HTMLTextAreaElement>) {
  this.countUpdate.emit(e.target.value);
}

@smnbbrv kasus saya adalah lokasi file img kemudian menampilkan img, berdasarkan SO Template: <img [src]="url"> <br/> <input type='file' (change)="showImg($event)">Komponen: ... this.url = event.target.result;Kadang-kadang berfungsi kadang tidak, ketika tidak salah adalah error TS2339: Property 'result' does not exist on type 'EventTarget'Seperti yang Anda sarankan, beri tahu TS lebih lanjut tentang hal itu, di tempat HTMLTextAreaElementsaya mencoba HTMLInputElementmaka target.valuetidak lagi err tapi gambar tidak ditampilkan.
Jeb50

Saya terkejut melihat bahwa Anda tidak bisa memasukkan tipe ke dalam Eventtipe. Anda harus benar-benar dapat menggunakan Event<HTMLInputElement>sebagai tipe.
Ronan

Acara @RoRo telah mengikuti sifat yang mirip: target, currentTargetdan srcElement; seseorang perlu mengetikkan 3 tipe generik; bahkan jika mereka menggunakan tipe default misalnya Event<T = any, C = any, S = any>untuk yang disebutkan di atas, ini bisa jadi lebih tidak nyaman digunakan daripada aspernyataan sederhana . Saya juga bisa membayangkan perang suci potensial untuk apa yang seharusnya menjadi generik pertama: targetatau currentTarget. Selain itu, banyak perpustakaan menyalahgunakan acara HTML dan berpotensi menempatkan apa pun yang mereka inginkan di properti yang disebutkan. Mungkin ini adalah alasan mengapa mereka tidak melakukannya sebagai obat generik
bawaan

Untuk bilah pencarian ion saya, saya menggunakan(ionChangeEvent.target as HTMLIonInputElement).value as string
Cloud

40

Inilah pendekatan sederhana yang saya gunakan:

const element = event.currentTarget as HTMLInputElement
const value = element.value

Kesalahan yang ditunjukkan oleh compiler TypeScript hilang dan kode berfungsi.


5
fromEvent<KeyboardEvent>(document.querySelector('#searcha') as HTMLInputElement , 'keyup')
    .pipe(
      debounceTime(500),
      distinctUntilChanged(),
      map(e  => {
            return e.target['value']; // <-- target does not exist on {}
        })
    ).subscribe(k => console.log(k));

Mungkin hal seperti di atas bisa membantu. Ubah berdasarkan kode yang sebenarnya. Masalahnya adalah ........ target ['value']


2

Saya percaya itu harus berhasil tetapi dengan cara apa pun saya tidak dapat mengidentifikasi. Pendekatan lain bisa jadi,

<textarea (keyup)="emitWordCount(myModel)" [(ngModel)]="myModel"></textarea>


export class TextEditorComponent {
   @Output() countUpdate = new EventEmitter<number>();

   emitWordCount(model) {
       this.countUpdate.emit(
         (model.match(/\S+/g) || []).length);
       }
}

2

Ini adalah pendekatan sederhana lainnya, yang saya gunakan;

    inputChange(event: KeyboardEvent) {      
    const target = event.target as HTMLTextAreaElement;
    var activeInput = target.id;
    }

2

Karena saya mencapai dua pertanyaan untuk mencari masalah saya dengan cara yang sedikit berbeda, saya mengulangi jawaban saya jika Anda berakhir di sini.

Dalam fungsi yang dipanggil, Anda dapat menentukan tipe Anda dengan:

emitWordCount(event: { target: HTMLInputElement }) {
  this.countUpdate.emit(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 }

Anda juga bisa lebih spesifik dan daripada menggunakan HTMLInputElementAnda bisa menggunakan misalnya HTMLTextAreaElementuntuk textareas.


1

Berikut satu cara lagi untuk menentukan event.target:

import { Component, EventEmitter, Output } from '@angular/core';

@Component({
    selector: 'text-editor',
    template: `<textarea (keyup)="emitWordCount($event)"></textarea>`
})
export class TextEditorComponent {

   @Output() countUpdate = new EventEmitter<number>();

    emitWordCount({ target = {} as HTMLTextAreaElement }) { // <- right there

        this.countUpdate.emit(
          // using it directly without `event`
            (target.value.match(/\S+/g) || []).length);
    }
}

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.