A propriedade 'valor' não existe no tipo EventTarget no TypeScript


118

Portanto, o código a seguir está em Angular 4 e não consigo descobrir por que ele não funciona da maneira esperada.

Aqui está um snippet do meu manipulador:

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

Elemento HTML:

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

O código me dá o erro:

A propriedade 'valor' não existe no tipo 'EventTarget'.

Mas, como pode ser visto no, console.logesse valor existe no event.target.


2
podemos usar (e.target como HTMLInputElement) .value
— user1162084

Respostas:


147

event.targetaqui está um HTMLElementque é o pai de todos os elementos HTML, mas não é garantido que tenha a propriedade value. O TypeScript detecta isso e gera o erro. Transmita event.targetpara o elemento HTML apropriado para garantir HTMLInputElementque ele tenha uma valuepropriedade:

(<HTMLInputElement>event.target).value

Pela documentação :

Digite o $event

O exemplo acima converte o $eventcomo um anytipo. Isso simplifica o código com um custo. Não há informações de tipo que possam revelar propriedades do objeto de evento e evitar erros bobos.

[...]

O $eventagora é um específico KeyboardEvent. Nem todos os elementos têm uma valuepropriedade, então ela é convertida targetem um elemento de entrada.

(Ênfase minha)


26
Sintaxe um pouco mais limpavar element = ev.target as HTMLElement
— Adrian Moisa

Para mim, HTMLInputElement funcionou em vez de HTMLElement, pois HTMLElement não tem valor na interface.
— Harsha Vardhini

1
A melhor abordagem, na minha opinião, é ter onFieldUpdate(event: { target: HTMLInputElement }) {na função chamada. Veja minha resposta abaixo.
— belvederef

Para Angular 9, use a sintaxe "como". event.target as HtmlInputlement
— Prescol 01 de

87

Passar HTMLInputElement como um genérico para o tipo de evento também deve funcionar:

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

14
Isso é melhor do que afirmações de tipo.
— JamesYin

2
Isso não funcionará se a função for chamada, por exemplo, de uma onChangereferência de manipulador de propriedade no código React. O manipulador de reação não espera que o tipo seja definido para React.ChangeEvent e mostrará um erro de digitação. I teve de voltar a (uma variante de) a resposta seleccionada em vez disso, com um molde: (event.target as HTMLInputElement).value.
— Spiralis

Isso pareceu funcionar bem para mim em um componente React. Talvez seja a versão do React? No momento, estamos em 16.8. *.
— hellatan

49

Aqui está outra correção que funciona para mim:

(event.target as HTMLInputElement).value

Isso deve eliminar o erro, informando ao TS que event.targeté um HTMLInputElement, que inerentemente tem um value. Antes de especificar, o TS provavelmente só sabia que eventsozinho era um HTMLInputElement, portanto, de acordo com o TS, o valor digitado targetera algum valor mapeado aleatoriamente que poderia ser qualquer coisa.


4
Isso foi muito útil no React, onde tentou interpretar <HTMLInputElement> como JSX.
— Christopher Bradshaw

Ei cara, obrigado por compartilhar! Essa solução se encaixa para mim.
— Carlos Querioz

16

Eu estava procurando uma solução para um erro semelhante do TypeScript com React:

A propriedade 'dataset' não existe no tipo EventTarget no TypeScript

Eu queria chegar a event.target.datasetum elemento de botão clicado no React:

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

Aqui está como eu consegui fazer o datasetvalor "existir" via 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
A pergunta está marcada como Angular, então uma resposta do React parece fora do assunto.
— John Snow

2
Independentemente disso ... ele tem vários votos positivos, portanto, essa resposta foi útil para outras pessoas.
— Beau Smith

1
Funciona como um encanto. onChange={(event: ChangeEvent<HTMLInputElement>): void => { setTextFilter(event.target.value); }}
— Vadorequest

3

A maneira como faço isso é a seguinte (melhor do que digitar assertion imho):

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

Isso pressupõe que você está interessado apenas na targetpropriedade, 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 tipo:

event: Event & { target: HTMLInputElement }

Esta é uma versão Vue.js, mas o conceito se aplica a todos os frameworks. Obviamente, você pode ir mais específico e em vez de usar um geral, HTMLInputElementvocê pode usar, por exemplo, HTMLTextAreaElementpara áreas de texto.


2

Você deve usar event.target.valueprop com o manipulador onChange, caso não consiga ver:

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

Ou se você quiser usar outro manipulador que não seja onChange, use event.currentTarget.value


isso funciona para mim, mas não tenho certeza se usar event.currentTarget.valueé a melhor abordagem.
— DCZI
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.