I use the @type/react-table
to set up the column for my table and I have error on my IDE complain that Cell
is not under correct type. I assume it is caused by Cell
is optional type from @type/react-table
how can I solve this?
//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();
});
});
The definition of Column
is a union of a bunch of different types describing possible column configurations. Only some of them have a Cell
property. ColumnGroup
does not. Therefore you don't know for sure that a variable of type Column
supports the Cell
property.
You can get around this by making your createColumn
function generic. It enforces that colDef
is assignable to TableColumn
but doesn't widen the type.
export function createColumn<C extends TableColumn>(colDef: C): C {
return colDef;
}
Now you get an error further down the chain because Cell
expects to be called with the complete CellProps
.
Update:
The current setup infers the type of the props for a valid Cell
in your column configuration as CellProps<ColumnValue, any>
. This means that you can just write Cell({value}) {
without specifying the props type.
You cannot make use of the inferred props type for Cell
of and also get typescript to infer that your particular Cell
only uses the prop value
from those (at least not without some advanced Typescript trickery).
It's easy to declare that the Cell
only needs a value prop, but you have to state that explicitly.
export const name = createColumn({
id: 'name',
Header: 'Name Column',
Cell({value}: {value: ColumnValue}) {
return value.hyperlink
},
});
The render
method of React Testing Library expects to be called with a ReactElement
. Right now your Cell
returns any
due to the loose definition of ColumnValue {[key: string]: any;}
. But probably value.hyperlink
is a string
which would be a Typescript error. You should wrap it in a fragment, either in the Cell
itself or in the render
.
export const name = createColumn({
id: 'name',
Header: 'Name Column',
Cell({value}: {value: {hyperlink: string}}) {
return value.hyperlink
},
});
The above definition will cause an error in the test so you need to do this:
const { getByText } = render(
<>
{name.Cell({
value: { hyperlink: "asadasd" }
})}
</>
);