简体   繁体   English

TypeScript 3:类型中缺少属性

[英]TypeScript 3: property is missing in type

I'm working on a ReactJS app with TypeScript. 我正在使用TypeScript开发ReactJS应用程序。 I was using TypeScript 2.8 with no problem, but 2.9 and 3 give me a new error. 我使用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;

I get the following error: 我收到以下错误:

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; }'.

I think that the type system wants a guarantee that the value passed will be a valid one (ie "firstName" or "lastName"). 我认为类型系统希望保证传递的值将是有效值(即“ firstName”或“ lastName”)。 I'm not sure about what construct to apply (and how to apply it) to appese the compiler. 我不确定要应用什么构造(以及如何应用)构造编译器。 I think I need to extract an interface and use it in two places: where I define the state in the component, and somewhere in the handleChange method. 我想我需要提取一个接口并在两个地方使用它:在组件中定义状态的地方和在handleChange方法中的某个地方。

Any suggestions would be appreciated. 任何建议,将不胜感激。

The problem is that your state is defined, in typescript yes, as a Record with keys firstname and lastname . 问题是,您的状态以打字稿yes的形式定义为具有firstnamelastname键的Record When event.target.id is a wider type string , although in your case it's recognised as number for some reason. event.target.id是更宽泛的类型string ,尽管在您的情况下由于某种原因它被识别为number

One way would be to cast it to any like (UPDATED): 一种方法是将其转换为any像(修订版):

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

In this case I suppose it wouldn't matter much, because there is no typesafety in this statement from the beginning 在这种情况下,我想没关系,因为从一开始该语句就没有类型安全性。

I think to get a more reliable type check you could add a handler for each input like this 我认为要获得更可靠的类型检查,您可以像这样为每个输入添加一个处理程序

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

Then to add a handler 然后添加一个处理程序

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

If you rely on the input id you cannot guarantee that the state field will match, it may compile but it won't actually be type checking. 如果您依靠输入ID,则不能保证state字段会匹配,它可以编译,但实际上不会进行类型检查。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM