Pesquisa de site

angular - Propriedade 'value' não existe no tipo 'EventTarget'


Estou usando a versão 2 do TypeScript para um código de componente Angular 2.

Estou recebendo o erro "Property 'value' does not exist on type 'EventTarget'" para o código abaixo, qual poderia ser a solução. Obrigado!

e.target.value.match(/\S+/g) || []).length
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);
  }
}

Resposta #1

Você precisa informar explicitamente ao TypeScript o tipo do HTMLElement que é o seu alvo.

A maneira de fazer isso é usando um tipo genérico para convertê-lo para um tipo apropriado:

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

ou (como você quiser)

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

ou (novamente, questão de preferência)

const target = e.target as HTMLTextAreaElement;

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

Isso fará com que o TypeScript saiba que o elemento é um textarea e ele conhecerá a propriedade value.

O mesmo poderia ser feito com qualquer tipo de elemento HTML, sempre que você der ao TypeScript um pouco mais de informações sobre seus tipos, ele lhe retorna com sugestões apropriadas e, claro, menos erros.

Para facilitar no futuro, você pode querer definir diretamente um evento com o tipo de seu alvo:

// 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);
}

Resposta #2

Aqui está a abordagem simples que usei:

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

O erro mostrado pelo compilador TypeScript desapareceu e o código funciona.

Resposta #3

Para aqueles que estão recebendo este erro no Angular 13, desde a atualização de uma versão anterior

O problema para mim era que eu estava usando o seguinte no meu HTML (o que antes era permitido)

(keyup)="applyFilter($event.target.value)" 

A correção para isso foi:

HTML :

(keyup)="applyFilter($event)"

Componente - na minha função chamada:

applyFilter(event: Event) {
    const filterValue = (event.target as HTMLInputElement).value;
    // ... etc...
}

E agora eu poderia usar filterValue novamente como antes.

Resposta #4

No meu caso, eu tinha:

const handleOnChange = (e: ChangeEvent) => {
  doSomething(e.target.value);
}

E o problema era que eu não forneci um argumento de tipo para ChangeEvent para que ele soubesse que e.target era um HTMLInputElement. Mesmo que eu dissesse manualmente que target era um elemento de input (por exemplo, const target: HTMLInputElement=e.target), o ChangeEvent ainda não sabia que isso fazia sentido.

A solução foi fazer:

// add type argument
const handleOnChange = (e: ChangeEvent<HTMLInputElement>) => {
  doSomething(e.target.value);
}

Resposta #5

Como cheguei a duas perguntas procurando meu problema de uma maneira um pouco diferente, estou replicando minha resposta caso você acabe aqui.

Na função chamada, você pode definir seu tipo com:

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

Isso assume que você está interessado apenas na propriedade target, que é o caso mais comum. Se você precisar acessar as outras propriedades de event, uma solução mais abrangente envolve o uso do operador de interseção de tipos &:

event: Event & { target: HTMLInputElement }

Você também pode ser mais específico e, ao invés de usar HTMLInputElement, pode usar, por exemplo, HTMLTextAreaElement para áreas de texto.

Resposta #6

Angular 10+

Abra tsconfig.json e desative strictDomEventTypes.

  "angularCompilerOptions": {
    ....
    ........
    "strictDomEventTypes": false
  }

Resposta #7

Não use as soluções alternativas de outras respostas que envolvem converter o evento, o alvo do evento ou desabilitar completamente a verificação de tipos. Isso não é seguro.

Em vez disso, você deve "extrair" o valor do elemento HTML e passar isso como um argumento.

Exemplo simplificado demais:

<input #searchBox type="text" (input)="doSearch(searchBox.value)">
doSearch(text: string): void {
}

Então, se você expandir isso para o exemplo original, você deve obter isto:

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

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

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

Resposta #8

considerar $any()

<textarea (keyup)="emitWordCount($any($event))"></textarea>

Resposta #9

Aqui está outra abordagem simples que eu usei;

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

Artigos relacionados