Dans mon application de réaction et TypeScript, j'utilise: onChange={(e) => data.motto = (e.target as any).value}
.
Comment définir correctement les typages pour la classe afin de ne pas avoir à me familiariser avec le système de type avec any
?
export interface InputProps extends React.HTMLProps<Input> {
...
}
export class Input extends React.Component<InputProps, {}> {
}
Si je mets target: { value: string };
je reçois:
ERROR in [default] /react-onsenui.d.ts:87:18
Interface 'InputProps' incorrectly extends interface 'HTMLProps<Input>'.
Types of property 'target' are incompatible.
Type '{ value: string; }' is not assignable to type 'string'.
Généralement, les gestionnaires d’événements doivent utiliser e.currentTarget.value
, par exemple:
onChange = (e: React.FormEvent<HTMLInputElement>) => {
const newValue = e.currentTarget.value;
}
Vous pouvez lire pourquoi cela se trouve ici https://github.com/DefinitelyTyped/DefinitelyTyped/pull/12239
UPD: Comme mentionné par @ roger-gusmao ChangeEvent
, il est plus approprié pour la saisie d'événements de formulaire.
onChange = (e: React.ChangeEvent<HTMLInputElement>)=> {
const newValue = e.target.value;
}
la façon correcte d'utiliser dans TypeScript est
handleChange(e: React.ChangeEvent<HTMLInputElement>) {
// No longer need to cast to any - hooray for react!
this.setState({temperature: e.target.value});
}
render() {
...
<input value={temperature} onChange={this.handleChange} />
...
);
}
Suivez le cours complet, il vaut mieux comprendre:
import * as React from "react";
const scaleNames = {
c: 'Celsius',
f: 'Fahrenheit'
};
interface TemperatureState {
temperature: string;
}
interface TemperatureProps {
scale: string;
}
class TemperatureInput extends React.Component<TemperatureProps, TemperatureState> {
constructor(props: TemperatureProps) {
super(props);
this.handleChange = this.handleChange.bind(this);
this.state = {temperature: ''};
}
// handleChange(e: { target: { value: string; }; }) {
// this.setState({temperature: e.target.value});
// }
handleChange(e: React.ChangeEvent<HTMLInputElement>) {
// No longer need to cast to any - hooray for react!
this.setState({temperature: e.target.value});
}
render() {
const temperature = this.state.temperature;
const scale = this.props.scale;
return (
<fieldset>
<legend>Enter temperature in {scaleNames[scale]}:</legend>
<input value={temperature} onChange={this.handleChange} />
</fieldset>
);
}
}
export default TemperatureInput;
as HTMLInputElement
fonctionne pour moi
La target
que vous avez essayé d'ajouter dans InputProps
n'est pas la même target
que vous vouliez qui est dans React.FormEvent
La solution que je pouvais trouver était donc d'étendre les types liés aux événements pour ajouter votre type de cible, comme suit:
interface MyEventTarget extends EventTarget {
value: string
}
interface MyFormEvent<T> extends React.FormEvent<T> {
target: MyEventTarget
}
interface InputProps extends React.HTMLProps<Input> {
onChange?: React.EventHandler<MyFormEvent<Input>>;
}
Une fois que vous avez ces classes, vous pouvez utiliser votre composant d’entrée comme
<Input onChange={e => alert(e.target.value)} />
sans erreurs de compilation. En fait, vous pouvez également utiliser les deux premières interfaces ci-dessus pour vos autres composants.
heureusement, je trouve une solution ... vous pouvez
importer {ChangeEvent} de 'réagir';
puis écrivez un code tel que: e:ChangeEvent<HTMLInputElement>
Voici un moyen de déstructurer les objets ES6, testé avec TS 3.3.
Cet exemple concerne une entrée de texte.
name: string = '';
private updateName({ target }: { target: HTMLInputElement }) {
this.name = target.value;
}