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.

Ravy
fonte
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)

Andrew Li
fonte
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;
}
Mikael Lirbank
fonte
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.

Matt S.
fonte
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…
}
Beau Smith
fonte
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.

Belvederef
fonte
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

JillAndMe
fonte
isso funciona para mim, mas não tenho certeza se usar event.currentTarget.valueé a melhor abordagem.
DCZI