【问题标题】:TypeScript 3: property is missing in typeTypeScript 3:类型中缺少属性
【发布时间】:2019-02-07 00:14:30
【问题描述】:

我正在使用 TypeScript 开发一个 ReactJS 应用程序。我使用 TypeScript 2.8 没有问题,但是 2.9 和 3 给了我一个新错误。

import * as React from 'react';


class ExampleComponent extends React.Component<{}, {
        firstName: string, lastName: string
    }> {
    clearState() {
        this.setState({
            firstName: "",
            lastName: ""
        });
    }

    constructor(props) {
        super(props);
        this.state = {
            firstName: '', lastName: ''
        };

        this.handleChange = this.handleChange.bind(this);
    }

    handleChange(event) {
       //***** This is the line that gives me an error ******
        this.setState({ [event.target.id]: event.target.value });

    }
    public render() {

        return <form>

            <div className="form-group">
                <div className="row">
                    <div className="col">
                        <label className="sr-only">First Name</label>
                        <input type="text" className="form-control name-element" id="firstName"
                            placeholder="First Name" value={this.state.firstName} onChange={this.handleChange} required={true} />
                    </div>

                    <div className="col">
                        <label className="sr-only">Last Name</label>
                        <input type="text" className="form-control name-element" id="lastName"
                            placeholder="Last Name" value={this.state.lastName} onChange={this.handleChange} required={true} />
                    </div>
                </div>
            </div>

        </form>

    }
}

// Wire up the React component to the Redux store
export default ExampleComponent;

我收到以下错误:

Error   TS2345  (TS) Argument of type '{ [x: number]: any; }' is not assignable to parameter of type '{ firstName: string; lastName: string; } | ((prevState: Readonly<{ firstName: string; lastName: string; }>, props: {}) => { firstName: string; lastName: string; } | Pick<{ firstName: string; lastName: string; }, "firstName" | "lastName">) | Pick<...>'.
  Type '{ [x: number]: any; }' is not assignable to type 'Pick<{ firstName: string; lastName: string; }, "firstName" | "lastName">'.
    Property 'firstName' is missing in type '{ [x: number]: any; }'.

我认为类型系统需要保证传递的值是有效值(即“firstName”或“lastName”)。我不确定要应用什么构造(以及如何应用它)来安抚编译器。我想我需要提取一个接口并在两个地方使用它:我在组件中定义状态的地方,以及在 handleChange 方法中的某个地方。

任何建议将不胜感激。

【问题讨论】:

    标签: reactjs typescript typescript3.0


    【解决方案1】:

    问题是您的状态在打字稿中定义为Record,键为firstnamelastname。当event.target.id 是更广泛的类型string 时,尽管在您的情况下由于某种原因它被识别为number

    一种方法是将其转换为any,例如(已更新):

    handleChange(event) {
        this.setState({ [event.target.id]: event.target.value } as any);
    }
    

    在这种情况下,我想这并不重要,因为从一开始这个语句就没有类型安全

    【讨论】:

    • 不幸的是,这些似乎都不起作用。这三个都给出了相同的编译错误。
    • ``` handleChange(event) { this.setState({ [event.target.id]: event.target.value } as any); } ```
    • 做到了!你能修正你的答案,我会投票并标记正确吗? (我不是投反对票的人)
    • 谢谢!我建议您也删除最后两个建议,因为它们似乎都不适合我。
    • 谢谢!我花了一整天的时间寻找这个答案!
    【解决方案2】:

    我认为要获得更可靠的类型检查,您可以像这样为每个输入添加一个处理程序

    function makeHandler(
        id: WhatEnumYourIdIs
    ): (event: React.SyntheticEvent<HTMLInputElement>) => void {
        return function(event: React.SyntheticEvent<HTMLInputElement>): void{
            this.setState({ id: target.value });
        }
    }
    

    然后添加一个处理程序

    <input onChange={this.makeHandler(Enum.FirstName)} />
    

    如果您依赖输入 id,则无法保证 state 字段会匹配,它可能会编译但实际上不会进行类型检查。

    【讨论】:

    • 谢谢。问题出在我的实际代码中,而不是两个字段,我有八个。基本上有八个方法处理程序做同样的事情感觉不太好,在更新的 TypeScript 之前我只需要一个。我希望有一些方法可以在只保留一个功能的同时安抚编译器。
    • 在这种情况下,通常对于这样的事情,我会使用第一个参数,如果你想使用 typescript 的真正力量,你想确保你使用任何类型来检查所有可能的类型应该是最后的手段,而且很少有必要。我会用一个例子来更新我的例子
    猜你喜欢
    • 2015-12-02
    • 1970-01-01
    • 2017-11-10
    • 2021-06-24
    • 1970-01-01
    • 2016-08-15
    • 2021-01-05
    • 1970-01-01
    • 2019-08-03
    相关资源
    最近更新 更多