具有定义道具和状态的问题

问题描述 投票:0回答:1

我收到以下错误:

类型为'{[x:number]的参数:任意; }'不可分配给'PostState |类型的参数((prevState:只读,道具:Readonly )=> PostState |选择| null)|选择<...> |空值'。类型“ {{[x:数字]:任何; }”,但必须在“ Pick”类型中输入。

在此行:

handleChange = ({target} : any) => {
        const {name, value} = target;
        this.setState({[name]: value}); // I GET THE ERROR HERE
    };

这是我的代码:

interface Post{
name: string;
body: string;
title: string;
_id: number | string;
date: Date;
}

interface PostState{
posts: Post[];
}
class ABC extends React.Component <{},PostState> {
    state = {
        title: '',
        name: '',
        date: '',
        body: '',
        posts: []
    };

    handleChange = ({target} : any) => {
        const {name, value} = target;
        this.setState({[name]: value});
    };
    submit = (event : any) => {
        event.preventDefault();
        const payload = {
            title: this.state.title,
            body: this.state.body,
            name: this.state.name
        };

        axios({url: 'http://localhost:8080/api/save/', method: 'POST', data: payload}).then(() => {
            console.log("Data has been sent to the server");
            this.resetUserInputs();
        }).catch(() => {
            console.log("Internal server error");
        })
    };

    resetUserInputs = () => {
        this.setState({title: '', body: '', name: ''})
    };

    render() {
        console.log('state', this.state);
        return (
            <div>
                <Nav/>
                <Box>
                    <Title>
                        <TextName>New Question</TextName>
                    </Title>
                    <form onSubmit={this.submit}>

                        <div className="form-input">
                            <H5 >Name
                                <InputName
                                    type="text"
                                    name="name"
                                    placeholder="Enter your full name here"
                                    value={this.state.name}
                                    onChange={this.handleChange}/>
                            </H5>
                        </div>

                        <div className="form-input">
                            <H5 >Title
                                <InputTitle
                                    type="text"
                                    name="title"
                                    placeholder="What's your question? Be specific"
                                    value={this.state.title}
                                    onChange={this.handleChange}/>
                            </H5>
                        </div>

                        <div className="form-input">
                            <QuestionText >Question</QuestionText>
                            <Questionbox
                                placeholder="Start your question with What OR How OR Why"
                                name="body"
                                rows={4}
                                cols={30}
                                value={this.state.body}
                                onChange={this.handleChange}/>
                        </div>

                        <Footer>
                            <div className="post-form-buttons">

                                <Button>Add Question</Button>
                                <Cancel>
                                    <Link href={`/`}>
                                        <A>
                                            Cancel
                                        </A>
                                    </Link>
                                </Cancel>
                            </div>
                        </Footer>

                    </form>
                </Box>
            </div>
        );
    }
}

export default ABC
reactjs typescript types next.js
1个回答
0
投票

您看到的问题错误是由于this.setState中使用了索引,而PostState接口中未定义索引签名。

像这样添加索引签名将消除此错误。

  interface PostState{
    posts: Post[];
    [key: string]: any;
  }

此外,您还可以将目标定义为事件,并告诉打字稿目标是具有namevalue属性的输入,以提供更多的类型安全性

  handleChange = ({target}: Event) => {
      const {name, value} = target as HTMLInputElement;
      this.setState({[name]: value});
  };

我注意到的另一件事是,您似乎将状态键设置为单个帖子的键,但将状态定义为具有一组帖子。

详细说明高级修复

是的,尽管您将需要使用TypeType的多个类型和一些更高级的功能,但是可以用更安全的类型来解决此问题。

类似于下面的代码会让您接近,但是仍然存在一个小问题,即您的状态是使用date属性定义为字符串,并且在Post界面中将其定义为Date的实例。您必须通过定义联合或通过创建另一个将date属性定义为字符串的单独接口来决定如何解决此问题。

interface Post {
  name: string;
  body: string;
  title: string;
  _id?: number | string;
  date: Date;
}

interface PostsArray {
  posts: string[];
}

type JoinedTypes = Post & PostsArray;

type PostState = {[P in keyof JoinedTypes]: JoinedTypes[P]}
© www.soinside.com 2019 - 2024. All rights reserved.