Skip to content

accessor getValue() loses undefined for key paths with optional keys #6238

@sandrina-p

Description

@sandrina-p

TanStack Table version

8.21.3

Framework/Library version

React 18/19

Describe the bug and the steps to reproduce it

When using columnHelper.accessor() with an optional path, the getValue() is inferred ignoring the undefined. It's hard to explain in words, here's an example:

import { createColumnHelper } from '@tanstack/react-table';
type Row = {
  user: {
    salary?: {
      amount: number;
    };
  };
};

const columnHelper = createColumnHelper<Row>();
const columns = [
  columnHelper.accessor('user.salary.amount', {
    cell: (row) => {
      const amount = row.getValue();
      // Expected: number | undefined
      // 🐛 Actual: number (optional `salary` not reflected)
      return amount;
    },
  }),
];

Cause

(This part was generated by Claude, might be wrong!)
DeepValue in @tanstack/table-core is approximately:

export type DeepValue<T, TProp> = T extends Record<string | number, any>
  ? TProp extends `${infer TBranch}.${infer TDeepProp}`
    ? DeepValue<T[TBranch], TDeepProp>
    : T[TProp & string]
  : never;

For optional salary, T[TBranch] becomes a union including undefined. The recursive conditional does not reliably propagate “path can be undefined” to the final leaf type, so optional parents along the path are effectively dropped from the inferred cell value type.

As workaround we've been using the callback fn, but the string is easier/faster to type. accessor: (row) => row.user.salary?.amount so the return type is inferred from the expression.

Could you take a look please to fix the string path? Thank you!

Your Minimal, Reproducible Example - (Sandbox Highly Recommended)

https://stackblitz.com/edit/tanstack-table-peddhmfe?file=src%2Fmain.tsx&preset=node

Screenshots or Videos (Optional)

Image

Do you intend to try to help solve this bug with your own PR?

None

Terms & Code of Conduct

  • I agree to follow this project's Code of Conduct
  • I understand that if my bug cannot be reliable reproduced in a debuggable environment, it will probably not be fixed and this issue may even be closed.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions