Typescript 'keyof' 关键字在使用 react setState 函数时出错

Posted

技术标签:

【中文标题】Typescript \'keyof\' 关键字在使用 react setState 函数时出错【英文标题】:Typescript 'keyof' keyword makes error when using with react setState functionTypescript 'keyof' 关键字在使用 react setState 函数时出错 【发布时间】:2018-11-15 20:10:16 【问题描述】:

我正在用 react 和 typescript 编写 Simple LoginForm。

interface State 
    username: string;
    password: string;


class LoginForm extends React.Component<Props, State> 
    readonly state: Readonly<State> = 
        username: '',
        password: ''
    

    onChange = (key: keyof State) => (e: React.FormEvent<htmlInputElement>) => 
        const value = e.currentTarget.value;
        this.setState( [key]: value );  // error
    

    render() 
        return (
            ...
            <TextField
                ...
                onChange=this.onChange('username')
            />
            <TextField
                ...
                onChange=this.onChange('password')
            />
            ...
        )
    

Typescript 在 setState 行中编译失败,出现错误。

类型参数 ' [x: string]: string; ' 不可分配给“State |”类型的参数((prevState: Readonly, props: Props) => State | Pick'. 类型 ' [x: string]: string; 中缺少属性 'username' '。

this.onChange 函数中的“key”参数只允许“用户名”或“密码”,如我所料。这意味着打字稿知道 typeof 'key' 参数必须是 'username' 或 'password'。这很明显,因为我将其定义为 (key: key of State)。

但是为什么在 setState 函数中,typeof 'key' 参数变成了普通字符串呢?

谢谢。

【问题讨论】:

【参考方案1】:

添加它作为替代方案,因为这解决了我的问题。

似乎在设置状态 this.setState(prop: value) 时,React TS 有时可以期待完整的 state@jcalz 对所选答案的推测。

this.setState(
      ...this.state,
      [key]: value
);

有关此问题的最佳做法的更多信息,请点击此处: https://github.com/DefinitelyTyped/DefinitelyTyped/issues/26635

【讨论】:

【参考方案2】:

试试这个代码:

onChange = (key: keyof IState) => (event: React.FormEvent<HTMLInputElement>) => 
    this.setState(
      [key]: event.currentTarget.value
     as Pick<IState, keyof IState>);

【讨论】:

【参考方案3】:

您遇到了known TypeScript bug,其中联合类型的计算属性被扩展为索引签名。 看起来对于 TypeScript 3.0,这将是 fixed,但这并不确定。

您现在应该使用的解决方法是 assert 该对象是预期的类型:

this.setState( [key]: value  as Record<typeof key, typeof value>);

我对 React 不够熟悉,无法知道 setState() 是否期待完整的 State,但请注意 [key]: value Partial&lt;State&gt;,因为它不会同时包含键...和 ​​TypeScript不会抓住这个,因为key 是一个联合类型。所以在运行时要小心。您可能希望将断言作为

this.setState( [key]: value  as Partial<State>);

如果这导致了错误,那么你应该修复它。

希望对您有所帮助。祝你好运!

【讨论】:

谢谢。你节省了我的时间。

以上是关于Typescript 'keyof' 关键字在使用 react setState 函数时出错的主要内容,如果未能解决你的问题,请参考以下文章

TypeScript 中的“keyof typeof”是啥意思?

Typescript中括号和keyof的几个特殊用法

TypeScript keyof 和 typeof

TypeScript:在 keyof T 处获取属性的类型

[TypeScript] Query Properties with keyof and Lookup Types in TypeScript

Typescript中括号和keyof的几个特殊用法