Property 'value' does not exist on type 'EventTarget'

前端 未结 7 2078
深忆病人
深忆病人 2020-11-30 00:40

I am using TypeScript Version 2 for an Angular 2 component code.

I am getting error "Property \'value\' does not exist on type \'EventTarget\'" for below co

相关标签:
7条回答
  • 2020-11-30 01:18

    You need to explicitly tell TypeScript the type of the HTMLElement which is your target.

    The way to do it is using a generic type to cast it to a proper type:

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

    or (as you like)

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

    or (again, matter of preference)

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

    This will let TypeScript know that the element is a textarea and it will know of the value property.

    The same could be done with any kind of HTML element, whenever you give TypeScript a bit more information about their types it pays you back with proper hints and of course less errors.

    To make it easier for the future you might want to directly define an event with the type of its target:

    // 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);
    }
    
    0 讨论(0)
  • 2020-11-30 01:24

    Here is the simple approach I used:

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

    The error shown by TypeScript compiler is gone and the code works.

    0 讨论(0)
  • 2020-11-30 01:24

    I believe it must work but any ways I'm not able to identify. Other approach can be,

    <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);
           }
    }
    
    0 讨论(0)
  • 2020-11-30 01:27
    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));
    

    Maybe something like the above could help. Change it based on the real code. The issue is ........ target['value']

    0 讨论(0)
  • 2020-11-30 01:28

    Here is one more way to specify 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);
        }
    }

    0 讨论(0)
  • 2020-11-30 01:36

    Since I reached two questions searching for my problem in a slightly different way, I am replicating my answer in case you end up here.

    In the called function, you can define your type with:

    emitWordCount(event: { target: HTMLInputElement }) {
      this.countUpdate.emit(event.target.value);
    }
    

    This assumes you are only interested in the target property, which is the most common case. If you need to access the other properties of event, a more comprehensive solution involves using the & type intersection operator:

    event: Event & { target: HTMLInputElement }
    

    You can also go more specific and instead of using HTMLInputElement you can use e.g. HTMLTextAreaElement for textareas.

    0 讨论(0)
提交回复
热议问题