首页 > 解决方案 > React 中的组件拆分导致 TypeScript 错误

问题描述

下面的 React 组件是一个显示元素数据的表单,无论它是游戏还是团队。

在我决定从查询父组件中拆分表单之前,我的组件运行良好。

这是我的界面:

export interface ShowProps {
  readOnly: boolean
  query: object
  id?: string | number
  match: {
    params: {
      id: string
      elements: string}
    }
}

//team
export interface Elem {
  id: string;
  name?: string;
  [attr: string]: string | number | undefined
}

//game
export interface Elem {
  id: string;
  homeTeamScore?: number
  competition?: string
  round?: string
}

export interface Data {
  elem?: Elem
  [elements: string]: Elem | undefined
}

export interface Variable {
  id?: string | number
}

export interface FormElemProps {
  data: object
  elementName: string
  readOnly: boolean
  listPath: string
}

这非常有效(没有 TypeScript 错误):

class FormElemQuery extends Query<Data, Variable> {}

const Show = (props: ShowProps) => {
  const id = props.match.params.id
  return (
    <FormElemQuery query={props.query} variables={{ id }}>
    {({ data = {}, error, loading }) => {
      // manage loading
      // manage error
      if (data !== {}  && Object.keys(data).length > 0 ) {
        const elementName = Object.keys(data)[0]
        return (
            <form>
            {
              Object.keys(data[elementName] || {}).map(attr => {
                if (attr !== "id" && attr !== "__typename") {
                  return (
                    <div key={attr} className="form-group">
                      <label htmlFor={`${Object.keys(data)[0]}-${attr}`}>{attr}</label>
                      <input
                        type="text"
                        readOnly={props.readOnly}
                        className="form-control"
                        id={`${Object.keys(data)[0]}-${attr}`}
                        value={data[elementName]![attr] || ""}
                        />
                    </div>
                  )
                }
            }
          )
        }
            </form>
        );
      }
    }}
  </FormElemQuery>
  )
}

export default Show;

但是下面的拆分不起作用:

父组件:

class ShowQuery extends Query<Data, Variable> {}

const Show = (props: ShowProps) => {
  const id = props.match.params.id
  return (
    <ShowQuery query={props.query} variables={{ id }}>
    {({ data = {}, error, loading }) => {
      // loading management
      // error management
      if (data !== {}  && Object.keys(data).length > 0 ) {
        const elementName = Object.keys(data)[0]
        return (
          <FormElem
            data={data}
            elementName={elementName}
            readOnly={props.readOnly}
            listPath={props.match.params.elements}
            />
        );
      }
    }}
    </ShowQuery>
  )
}

export default Show;

表单组件:

const FormElem = (props: FormElemProps) =>  {
  return (
            <form>
            {
              Object.keys(props.data[props.elementName]).map(attr => {
                if (attr !== "id" && attr !== "__typename") {
                  return (
                    <div key={attr} className="form-group">
                      <label htmlFor={`${Object.keys(props.data)[0]}-${attr}`}>{attr}</label>
                      <input
                        type="text"
                        readOnly={props.readOnly}
                        className="form-control"
                        id={`${Object.keys(props.data)[0]}-${attr}`}
                        value={props.data[props.elementName]![attr] || ""}
                        />
                    </div>
                  )
                }
            }
          )
        }
            </form>
        );
}

export default FormElem;

这是我运行此代码时遇到的错误:

TypeScript error: Element implicitly has an 'any' type because type '{}' has no index signature.  TS7017

    16 |             <form>
    17 |             {
  > 18 |               Object.keys(props.data[props.elementName]).map(attr => {
       |                           ^
    19 |                 if (attr !== "id" && attr !== "__typename") {
    20 |                   return (
    21 |                     <div key={attr} className="form-group">

所以在 Object.keys 中使用 props 肯定有问题(据我了解,Object.keys 是不可索引的)。但我不知道该怎么做才能解决这个问题。

任何想法 ?

标签: reactjstypescript

解决方案


所以我data在组件未拆分时使用,并且props.dataForm拆分时,我改变了我dataFormElemProps界面中定义的方式:

export interface FormElemProps {
  data: {
    elem?: Elem
    [key: string]: Elem | undefined
  }
  // ...
}

推荐阅读