I want to create a custom table. The prop in the cell and footer in createColumnHelper function should return the correct object key/type instead of any.
For example, I have a nested object progress in my DATA. Or if not an object, it also should return the correct type.
I attached screenshots of how I see in the IDE
Helper.ts
import { ReactElement } from "react";
export type Column<T> = {
header: string | (() => ReactElement);
accessor: (row: T) => any;
cell?:(prop: any) => ReactElement | string;
footer?: (prop: any) => ReactElement | string;
};
export const createColumnHelper = <T>() => {
return {
accessor: (
accessor: keyof T | ((row: T) => any),
column: {
header: string | (() => ReactElement);
cell?: (prop: any) => ReactElement | string;
footer?: (prop: any) => ReactElement | string;
}
) => {
return {
header: column.header,
accessor: (row: T) => (typeof accessor === "function" ? accessor(row) : row[accessor]),
cell: column.cell,
footer: column.footer,
} as Column<T>;
}
};
};
TableComponents.tsx
import React from "react";
import { createColumnHelper } from "./columnHelper";
type Person = {
firstName: string
lastName: string
age: number
visits: number
status: string
progress: {
ok?: number;
no?: string
}
}
const DATA: Person[] = [
{
firstName: 'tanner',
lastName: 'linsley',
age: 24,
visits: 100,
status: 'In Relationship',
progress: {
ok: 50
},
},
{
firstName: 'tandy',
lastName: 'miller',
age: 40,
visits: 40,
status: 'Single',
progress: {
no: 'bad'
},
},
]
const columnHelper = createColumnHelper<Person>();
const columns = [
columnHelper.accessor(
'firstName', {
header: 'First Name',
cell: val => val,
}),
columnHelper.accessor(
'progress', {
header: 'Progress',
cell: prop => prop.ok,
}),
columnHelper.accessor(row => row, {
header: () => <span>Age</span>,
cell: prop => <span>{prop.age}</span>,
}),
];
const TableComponent: React.FC = () => {
return (
<table>
<thead>
<tr>
{columns.map((column, index) => (
<th key={index}>
{typeof column.header === "function" ? column.header() : column.header}
</th>
))}
</tr>
</thead>
<tbody>
{DATA.map((row, rowIndex) => (
<tr key={rowIndex}>
{columns.map((column, colIndex) => (
<td key={colIndex}>
{column.cell ? column.cell(column.accessor(row)) : column.accessor(row)}
</td>
))}
</tr>
))}
</tbody>
<tfoot>
<tr>
{columns.map((column, index) => (
<td key={index}>
{column.footer ? column.footer({ column }) : null}
</td>
))}
</tr>
</tfoot>
</table>
);
};
export default TableComponent;