“字符串”不能用于索引类型“{}”

新手上路,请多包涵

我有以下 React 组件,它从对象数组生成 HTML 表。应该显示的列是通过 tableColumns 属性定义的。

When looping through items and displaying the correct columns I have to use the key property from the tableColumn object ( {item[column.key]} ) but typescript is产生以下错误:

元素隐式具有“任何”类型,因为“字符串”类型的表达式不能用于索引类型“{}”。在“{}”类型上找不到带有“字符串”类型参数的索引签名。

我能做些什么来解决这个问题?我迷路了

我如何调用组件:

 <TableGridView
  items={[
    {
      id: 1,
      name: 'John Doe',
      email: 'john@doe.de'
    },
    {
      id: 2,
      name: 'Lorem ipsum',
      email: 'lorem@ipsum.com',
    }
  ]}
  tableColumns={[
    {
      key: 'id',
      label: 'ID',
    },
    {
      key: 'name',
      label: 'Name',
    }
  ]}
/>

我的组件:

 export type TableColumn = {
  key: string,
  label: string,
};

export type TableGridViewProps = {
  items: object[],
  tableColumns: TableColumn[]
};

const TableGridView: React.FC<TableGridViewProps> = ({ tableColumns, items }) => {
  return (
    <table>
      <tbody>
        {items.map(item => {
          return (
            <tr>
              {tableColumns.map((column, index) => {
                return (
                  <td
                    key={column.key}
                    className="lorem ipsum"
                  >
                    {item[column.key]} // error thrown here
                  </td>
                );
              })}
            </tr>
          );
        })}
      </tbody>
    </table>
  );
}

原文由 mxmtsk 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 509
2 个回答
  items: object[],

虽然从技术上讲它是一个 JavaScript 对象,但类型可以更好。要让 Typescript 在访问对象属性时正确帮助您识别错误,您需要告诉它对象的确切形状。如果您将其键入为 object ,则打字稿无法帮助您。相反,您可以告诉它对象具有的确切属性和数据类型:

   let assistance: { safe: string } = { safe: 1 /* typescript can now tell this is wrong */ };
  assistance.unknown; // typescript can tell this wont really work too

现在,在对象可以包含任何类型的键/值对的情况下,您至少可以通过使用对象索引类型来告诉 typescript 值(和键)具有什么类型:

  items: {
   [key: string]: number | string,
  }[]

在给定的情况下,这将是准确的类型。

原文由 Jonas Wilms 发布,翻译遵循 CC BY-SA 4.0 许可协议

首先,将 --- 的类型定义为 items objects 数组是一个坏主意,因为它违背了 Typescript 的目的。而是定义数组将包含什么类型的对象。我会这样做:

 type Item = {
  id: number,
  name: string,
  email: string,
}

export type TableGridViewProps = {
  items: Item[],
  tableColumns: TableColumn[]
};

之后,如果您完全确定 key 将存在于 item 中,您可以执行以下操作来告诉 Typescript 您正在访问一个有效的索引。

 <td
  key={column.key}
  className="lorem ipsum"
>
  {item[column.key as keyof typeof Item]}
</td>

原文由 Chan Jing Hong 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题