TanStack Table
TanStack Table column definitions require an accessor function and an id string when using a function accessor. These two values always refer to the same field — they must stay in sync manually. data-path keeps them in sync automatically: .fn provides the accessor function and .$ provides the string id.
Basic usage
Section titled “Basic usage”import { createColumnHelper } from "@tanstack/react-table";import { path } from "data-path";
type User = { id: string; contact: { email: string }; name: string };
const columnHelper = createColumnHelper<User>();
const emailPath = path((u: User) => u.contact.email);const namePath = path((u: User) => u.name);
const columns = [ columnHelper.accessor(namePath.fn, { id: namePath.$, header: "Name", cell: (info) => info.getValue(), }), columnHelper.accessor(emailPath.fn, { id: emailPath.$, header: "Email", cell: (info) => info.getValue(), }),];emailPath.fn is (u: User) => string | undefined — TanStack Table expects (row: T) => V. The types align directly.
Nested paths
Section titled “Nested paths”Deep paths work the same way — the column accessor and id stay in sync regardless of nesting depth:
type Order = { id: string; customer: { profile: { firstName: string; lastName: string } }; total: number;};
const firstNamePath = path((o: Order) => o.customer.profile.firstName);
columnHelper.accessor(firstNamePath.fn, { id: firstNamePath.$, // "customer.profile.firstName" header: "First name",})Sorting and filtering
Section titled “Sorting and filtering”The path string is also useful when configuring column sort fields or filter keys that reference the same property:
const columns = [ columnHelper.accessor(emailPath.fn, { id: emailPath.$, header: "Email", enableSorting: true, sortingFn: "alphanumeric", }),];
// In global filter, compare against path stringconst rowMatchesFilter = (row: User, filter: string) => emailPath.get(row)?.includes(filter) ?? false;Path-driven column registry
Section titled “Path-driven column registry”Build a column registry where path definitions drive both the accessor and the display name. Use Path<T, V> as the prop type, and specialize the helper to your row type (the ColumnHelper returned by createColumnHelper<User>() is already tied to User):
import type { Path } from "data-path";
function col<V>(p: Path<User, V>, header: string) { return columnHelper.accessor(p.fn, { id: p.$, header });}
const columns = [ col(namePath, "Name"), col(emailPath, "Email"),];If you want a row-type-agnostic helper, pass the columnHelper in and make the factory itself generic:
import type { ColumnHelper } from "@tanstack/react-table";import type { Path } from "data-path";
function makeCol<T>(helper: ColumnHelper<T>) { return <V>(p: Path<T, V>, header: string) => helper.accessor(p.fn, { id: p.$, header });}
const col = makeCol(columnHelper);const columns = [col(namePath, "Name"), col(emailPath, "Email")];See also
Section titled “See also”- Data access —
fn,get, andset - Types —
Path<T, V>andResolvedType