我正在创建一个通用函数来更改状态。
错误信息:
TS2345: Argument of type '() => { [x:string]: string }' is not assignable to parameter of type 'IUserSignUpState | Pick<IUserSignUpState, "url" | "errors"> | ((prevState: Readonly<IUserSignUpState>, props: Readonly<IUserSignUpState>) => IUserSignUpState | Pick<...> | null) null'.
Type '() => { [x: string] string; }' is not assignable to type '(prevState: Readonly<IUserSignUpState>, props: Readonly<IUserSignUpState>) => IUserSignupState | Pick<IUserSignUpState>, "url" | "errors" | null'.
Type '{ [x: string]: string; }' is not assignable to type 'IUserSignUpState | Pick<IUserSignUpState, "url" | "errors"> | null'.
Type '{ [x: string]: string; }' is missing the following properties from type 'Pick<IUserSignUpState, "url" | "errors">': url, errors.
这是通用更改功能的示例:
./UserSignUp.tsx
interface IUserSignUpState {
url: string;
errors: string[];
// following can be used, but will lose type checking (*)
// [key: string]: string;
}
class UserSignUp extends React.Component<{}, IUserSignUpState>
state = {
url: '',
name: '',
errors: [],
};
render() {
const { url, errors } = this.state;
return (
<form>
<input type="text" name="url" value={url} onChange={this.change} />
<input type="text" name="name" value={name} onChange={this.change} />
<form>
)
}
change = (event:React.ChangeEvent<HTMLInputElement>) => {
const name = event.target.name;
const value = event.target.value;
// gives error here:
this.setState(() => {
return {
[name]: value
}
})
}
};
在这个例子中,change 事件应该只被允许更新url: string;
和name: string;
,而不是errors: []
。
我应该定义 'url' 和 'name' 类型并以某种方式在 change 函数中重用它们吗?
*在 Typescript 文档中,它声明可以使用可索引类型。但是,这样做我将失去类型检查。一个副作用是我还可能设置“错误”状态,这通常不应该从更改函数中实现。
更新:根据此Stackoverflow Question 中的答案,以下解决方案是可能的:
拆分界面:
interface IInputState {
url: string;
}
interface IUserSignUpState extends IInputState {
errors: string[];
}
并通过以下任一方式重新使用该接口:
this.setState({ [name]: value } as Partial<IInputStates>)
或者:
const name = event.target.name as keyof IInputStates;
const value = event.target.value;
this.setState(():IInputStates => {
return { [name]: value }
});