TS2339:打字稿中来自@type/react-table 的类型上不存在属性“Cell”

时间:2021-03-19 14:20:04

标签: typescript typescript-typings typescript-generics react-table-v7 react-table-v6

我使用 @type/react-table 为我的表设置列,但我的 IDE 出现错误,抱怨 Cell 的类型不正确。我认为它是由 Cell@type/react-table 的可选类型引起的,我该如何解决这个问题?

//column.tsx
import {Column, Cell} from 'react-table';

export interface ColumnValue {
    [key: string]: any;
}
export type TableColumn = Column<ColumnValue>
export function createColumn(colDef: TableColumn): TableColumn {
  return colDef;
}
export const name = createColumn({
  id: 'name',
  Header: 'Name Column',
  Cell({value}}) {
    return value.hyperlink
  },
});


//column.test.tsx
import {render} from '@testing-library/react';
import {name} from './Name';

describe('Test Name Column', () => {

  it('shows the name', () => {
    const {getByText} = render(
      name.Cell({
      // Error show TS2339: Property 'Cell' does not exist on type 'TableColumn'
        value: {hyperlink: 'asadasd'}}),
      })
    );
    expect(getByText('i am name')).toBeTruthy();
  });
});

1 个答案:

答案 0 :(得分:1)

Column 的定义是一系列描述可能的列配置的不同类型的联合。只有其中一些具有 Cell 属性。 ColumnGroup 没有。因此,您不确定 Column 类型的变量是否支持 Cell 属性。

您可以通过使 createColumn 函数通用来解决此问题。它强制 colDef 可分配给 TableColumn,但不会扩展类型。

export function createColumn<C extends TableColumn>(colDef: C): C {
  return colDef;
}

现在,您会在链的更深处遇到错误,因为 Cell 期望使用完整的 CellProps 进行调用。


更新:

当前设置将列配置中有效 Cell 的道具类型推断为 CellProps<ColumnValue, any>。这意味着你可以只写 Cell({value}) { 而不指定 props 类型。

您不能为 Cell 使用推断的 props 类型,并且还获取打字稿来推断您的特定 Cell 仅使用来自那些(至少不是没有一些高级的 Typescript 技巧)。

声明 value 只需要一个 value 属性很容易,但您必须明确说明这一点。

Cell

React 测试库的 export const name = createColumn({ id: 'name', Header: 'Name Column', Cell({value}: {value: ColumnValue}) { return value.hyperlink }, }); 方法期望使用 render 调用。由于 ReactElement 的定义松散,现在您的 Cell 返回 any。但可能 ColumnValue {[key: string]: any;} 是一个 value.hyperlink 这将是一个 Typescript 错误。您应该将它包装在一个片段中,要么在 string 本身中,要么在 Cell 中。

render

上面的定义会导致测试出错,所以需要这样做:

export const name = createColumn({
  id: 'name',
  Header: 'Name Column',
  Cell({value}: {value: {hyperlink: string}}) {
    return value.hyperlink
  },
});