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

TS2339: Property 'Cell' does not exist on type from @type/react-table in typescript

我使用 @type/react-table 为我的 table 设置列,但我的 IDE 有错误,抱怨 Cell 类型不正确。我认为这是由 Cell is optional type from @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();
  });
});

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}) { 而无需指定道具类型。

您不能使用 Cell 的推断道具类型来推断您的特定 Cell 仅使用道具 value 来自那些(至少不是没有一些高级的 Typescript 技巧)。

声明 Cell 只需要一个价值道具很容易,但您必须明确说明。

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

React 测试库的 render 方法需要用 ReactElement 调用。由于 ColumnValue {[key: string]: any;} 的松散定义,现在您的 Cell returns any。但可能 value.hyperlink 是一个 string,这将是一个 Typescript 错误。您应该将其包装在一个片段中,在 Cell 本身或 render.

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

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

const { getByText } = render(
  <>
    {name.Cell({
      value: { hyperlink: "asadasd" }
    })}
  </>
);