I'd like to take advantage of the static and strong typing in TypeScript, but only for the state since I don't intend to take in any props.
When I attempt to pass the interface as such, I end up with an error:
import * as React from 'react';
import {Link} from 'react-router-dom';
import Constants from '../Constants';
interface ILoginState {
email: string;
password: string;
remember: boolean;
error: string;
isLoading: boolean;
}
class LoginView extends React.Component<{}, ILoginState> {
constructor(props) {
super(props);
this.state = {
email: '',
password: '',
remember: false,
error: '',
isLoading: false
};
}
render() {
return (<div>Login goes here</div>
);
}
}
export default LoginView;
I end up with a compile error:
ERROR in [at-loader] ./src/scripts/pages/LoginView.tsx:41:21
TS2345: Argument of type '{ [x: number]: any; }' is not assignable to parameter of type 'ILoginState | ((prevState: Readonly<ILoginState>, props: {}) => ILoginState | Pick<ILoginState, "...'.
Type '{ [x: number]: any; }' is not assignable to type 'Pick<ILoginState, "email" | "password" | "remember" | "error" | "isLoading">'.
Property 'email' is missing in type '{ [x: number]: any; }'.
I've also tried using 'any' in place of the empty brackets but that doesn't work either.
Here's the line 41 (this.SetState...) that the trace is referring to:
handleChange = event => {
const target = event.target;
const value = target.type === 'checkbox' ? target.checked : target.value;
this.setState({
[target.name]: value
});
}
Here are all examples where that's used:
<input name="email" type="email" value={this.state.email} onChange={this.handleChange} />
<input name="password" type="password" value={this.state.password} onChange={this.handleChange} />
<input name="remember" type="checkbox" checked={this.state.remember} onChange={this.handleChange} />
setStatecall. Do you have asetStatecall in that component that you left out of the example? If so, can you include it?event.target.nameis inferred to have typenumber(not sure why), andtarget.valuetypeany. Since the name inferred asnumber, I don't think you can cast it to bekeyof ILoginState(which would have been the best option). This may be one of those cases where the easiest thing is just to cast the state object to any. EG:this.setState({[target.name]: value} as any), since I'm not sure where thatnumberinference is coming from, or what you'd have to change to correct it. Hopefully someone who knows more about react can give a better answer.