我应该如何构建一个通用的ReactTypescript表单组件,其字段可以作为一个类型传递进来?

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

我的应用程序有许多类似的编辑表单,用于编辑不同种类的项目。我不想为每一种项目编写不同的表单组件,而是想编写一个通用组件,它可以接受一个typeinterface,然后显示一系列基于该类型的输入。

我试着使用typescript的generics语法和index signature语法来实现我想要的东西。我指定了一个通用类型 "T",它扩展了一个可以被字符串索引的类型,并返回一个字符串,然后指定通用类型作为组件的状态。然而,当我试图将字符串分配给状态时,我得到了一个错误。

类型'string'不可分配给类型'T[string]'。

下面是代码。

    type DataType {
        [index: string]: string
    }

    interface EditFormProps<T> {
        initialState: T,
        someCallback: (item: T) => any1,
    }

    export default class EditForm<T extends DataType> extends React.Component<EditFormProps<T>, T> {
        constructor(props: any) {
            super(props)
            this.state = props.initialState
        }

        someOtherFunction(someAttribute: string, someString: string) {
            this.setState({
                [someAttribute]: someString,    // Here is where I get the error above.
            })
        }
    }

实例化是这样的

    interface Foo extends DataType {
        foo: string,
        bar: string,
    }

    ...

    import Foo from 'Foo'
    import EditForm from 'EditForm'
    class EditFooForm extends EditForm<Foo> {}

    ...

    <EditFooForm
        initialState={{foo: "", bar: ""}}
        someCallback={(item: Foo) => {}}
    />

问题1:既然通用类型T在索引为字符串时保证返回一个字符串,而组件状态的类型为T,为什么当我将一个字符串分配给状态时,typecript会抱怨?

问题2:我的问题比较广泛,是不是整个方法都不可取?有没有更好的方法?

reactjs typescript generics ecmascript-6
1个回答
0
投票

我相信你的问题出在类型定义上。someAttribute:

    someOtherFunction(someAttribute: string, someString: string) {
        this.setState({
            [someAttribute]: someString,    // Here is where I get the error above.
        })

你使用 someAttribute 这是个 string 的实例进行索引。T. 字符串不能作为 T.

我想你应该可以用以下方法解决这个问题 keyof 关键字

    someOtherFunction(someAttribute: keyof T, someString: string) {

这样一来,你就有了限制 someAttribute 的有效索引值。T.

© www.soinside.com 2019 - 2024. All rights reserved.