Skip to content

fix ColumnHelper['accessor'] TValue type #5999

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

Smona
Copy link

@Smona Smona commented Apr 25, 2025

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>
        ),
    }),
],

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

ColumnDef types gives typescript error
1 participant