fix ColumnHelper['accessor'] TValue type
Fixes #4382
I ran into #4382 trying to write a generic, reusable wrapper around react-table. Looking into the issue brought me to the ColumnHelper type. I've had issues in the past when trying to transform one generic type parameter into a second, inferred generic parameter, and often it can be fixed using a distributive helper type instead. So I tried pulling out the TValue generic parameter into one, and then using that in ColumnHelper instead.
This seems to work! I'm able to create a properly typed, generic reusable wrapper component by defining the props like this:
type Columns<T> = {
[K in keyof Required<T>]: ColumnDef<T, T[K]>;
}[keyof Required<T>][];
type ColumnsBuilder<T> = (helper: ColumnHelper<T>) => Columns<T>;
interface Props<T> {
data: T[] | null;
columns: ColumnsBuilder<T>;
};
And the types are compatible, with no types lost:
type Person = {
id: number;
firstName: string;
lastName: string;
age?: number;
visits: number;
status: string;
};
// (ColumnDef<Person, number> | ColumnDef<Person, string> | ColumnDef<Person, number | undefined>)[]
type ColumnsType = Columns<Person>;
const columns: ColumnsBuilder<Person> = (columnHelper) => [
// Inferred as: <(p: Person) => string>(accessor: (p: Person) => string, column: DisplayColumnDef<Person, string>) => AccessorFnColumnDef<Person, string>
columnHelper.accessor((p) => p.firstName, {
header: 'First Name',
cell: (info) => <strong>{info.getValue()}</strong>,
}),
// inferred as: <"age">(accessor: "age", column: IdentifiedColumnDef<Person, number | undefined>) => AccessorKeyColumnDef<Person, number | undefined>
columnHelper.accessor('age', {
header: 'Last Name',
cell: (info) => <em>{info.getValue()}</em>,
}),
// inferred as: <"status">(accessor: "status", column: IdentifiedColumnDef<Person, string>) => AccessorKeyColumnDef<Person, string>
columnHelper.accessor('status', {
header: 'Status',
cell: (info) => (
<span
style={{
color: info.getValue() === 'Active' ? 'green' : 'red',
fontWeight: 'bold',
}}
>
{info.getValue()}
</span>
),
}),
],
@KevinVandy any changes you would like to see here? we've been using this type in our codebase for a while now without issue.