Skip to content

Commit 20a7121

Browse files
Faithfinderclaude
andcommitted
fix: add variance annotations to fix file-order-dependent type errors
Add `in out` (invariant) variance annotations to `TData` and `TValue` type parameters on all mutually recursive types in the ColumnDef/Column cycle (ColumnDefBase, Column, Cell, Header, CoreColumn, CoreCell, CoreHeader, HeaderContext, CellContext, GroupingColumnDef, and related ColumnDef variants). This works around a known TypeScript variance computation bug (microsoft/TypeScript#44572) where file processing order causes tsc to incorrectly cache TValue as [independent], silently making ColumnDef<Row, string> assignable to ColumnDef<Row, unknown>. Also makes TableFeature's createCell/createColumn/createHeader methods generic over TValue (instead of hardcoding unknown) so that the invariant TValue flows through correctly in implementation code. Fixes #6167 Related: #4241, #4382 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 827b098 commit 20a7121

9 files changed

Lines changed: 41 additions & 35 deletions

File tree

packages/table-core/src/core/cell.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { RowData, Cell, Column, Row, Table } from '../types'
22
import { Getter, getMemoOptions, memo } from '../utils'
33

4-
export interface CellContext<TData extends RowData, TValue> {
4+
export interface CellContext<in out TData extends RowData, in out TValue> {
55
cell: Cell<TData, TValue>
66
column: Column<TData, TValue>
77
getValue: Getter<TValue>
@@ -10,7 +10,7 @@ export interface CellContext<TData extends RowData, TValue> {
1010
table: Table<TData>
1111
}
1212

13-
export interface CoreCell<TData extends RowData, TValue> {
13+
export interface CoreCell<in out TData extends RowData, in out TValue> {
1414
/**
1515
* The associated Column object for the cell.
1616
* @link [API Docs](https://tanstack.com/table/v8/docs/api/core/cell#column)

packages/table-core/src/core/column.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import {
88
} from '../types'
99
import { getMemoOptions, memo } from '../utils'
1010

11-
export interface CoreColumn<TData extends RowData, TValue> {
11+
export interface CoreColumn<in out TData extends RowData, in out TValue> {
1212
/**
1313
* The resolved accessor function to use when extracting the value for the column from each row. Will only be defined if the column def has a valid accessor key or function defined.
1414
* @link [API Docs](https://tanstack.com/table/v8/docs/api/core/column#accessorfn)

packages/table-core/src/core/headers.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ export interface CoreHeaderGroup<TData extends RowData> {
1616
id: string
1717
}
1818

19-
export interface HeaderContext<TData, TValue> {
19+
export interface HeaderContext<in out TData, in out TValue> {
2020
/**
2121
* An instance of a column.
2222
*/
@@ -31,7 +31,7 @@ export interface HeaderContext<TData, TValue> {
3131
table: Table<TData>
3232
}
3333

34-
export interface CoreHeader<TData extends RowData, TValue> {
34+
export interface CoreHeader<in out TData extends RowData, in out TValue> {
3535
/**
3636
* The col-span for the header.
3737
* @link [API Docs](https://tanstack.com/table/v8/docs/api/core/header#colspan)

packages/table-core/src/features/ColumnFaceting.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,8 @@ export interface FacetedOptions<TData extends RowData> {
4646
//
4747

4848
export const ColumnFaceting: TableFeature = {
49-
createColumn: <TData extends RowData>(
50-
column: Column<TData, unknown>,
49+
createColumn: <TData extends RowData, TValue>(
50+
column: Column<TData, TValue>,
5151
table: Table<TData>
5252
): void => {
5353
column._getFacetedRowModel =

packages/table-core/src/features/ColumnFiltering.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ export type TransformFilterValueFn<TData extends RowData> = (
4848

4949
export type ColumnFilterAutoRemoveTestFn<TData extends RowData> = (
5050
value: any,
51-
column?: Column<TData, unknown>
51+
column?: Column<TData, any>
5252
) => boolean
5353

5454
export type CustomFilterFns<TData extends RowData> = Record<
@@ -266,8 +266,8 @@ export const ColumnFiltering: TableFeature = {
266266
} as ColumnFiltersOptions<TData>
267267
},
268268

269-
createColumn: <TData extends RowData>(
270-
column: Column<TData, unknown>,
269+
createColumn: <TData extends RowData, TValue>(
270+
column: Column<TData, TValue>,
271271
table: Table<TData>
272272
): void => {
273273
column.getAutoFilterFn = () => {
@@ -414,10 +414,10 @@ export const ColumnFiltering: TableFeature = {
414414
},
415415
}
416416

417-
export function shouldAutoRemoveFilter<TData extends RowData>(
417+
export function shouldAutoRemoveFilter<TData extends RowData, TValue>(
418418
filterFn?: FilterFn<TData>,
419419
value?: any,
420-
column?: Column<TData, unknown>
420+
column?: Column<TData, TValue>
421421
) {
422422
return (
423423
(filterFn && filterFn.autoRemove

packages/table-core/src/features/ColumnGrouping.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ export type AggregationFnOption<TData extends RowData> =
3434
| BuiltInAggregationFn
3535
| AggregationFn<TData>
3636

37-
export interface GroupingColumnDef<TData extends RowData, TValue> {
37+
export interface GroupingColumnDef<in out TData extends RowData, in out TValue> {
3838
/**
3939
* The cell to display each row for the column if the cell is an aggregate. If a function is passed, it will be passed a props object with the context of the cell and should return the property type for your adapter (the exact type depends on the adapter being used).
4040
* @link [API Docs](https://tanstack.com/table/v8/docs/api/features/grouping#aggregatedcell)

packages/table-core/src/features/ColumnOrdering.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -88,8 +88,8 @@ export const ColumnOrdering: TableFeature = {
8888
}
8989
},
9090

91-
createColumn: <TData extends RowData>(
92-
column: Column<TData, unknown>,
91+
createColumn: <TData extends RowData, TValue>(
92+
column: Column<TData, TValue>,
9393
table: Table<TData>
9494
): void => {
9595
column.getIndex = memo(

packages/table-core/src/features/GlobalFiltering.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ export interface GlobalFilterOptions<TData extends RowData> {
4646
* @link [API Docs](https://tanstack.com/table/v8/docs/api/features/global-filtering#getcolumncanglobalfilter)
4747
* @link [Guide](https://tanstack.com/table/v8/docs/guide/global-filtering)
4848
*/
49-
getColumnCanGlobalFilter?: (column: Column<TData, unknown>) => boolean
49+
getColumnCanGlobalFilter?: (column: Column<TData, any>) => boolean
5050
/**
5151
* The filter function to use for global filtering.
5252
* - A `string` referencing a built-in filter function
@@ -118,8 +118,8 @@ export const GlobalFiltering: TableFeature = {
118118
} as GlobalFilterOptions<TData>
119119
},
120120

121-
createColumn: <TData extends RowData>(
122-
column: Column<TData, unknown>,
121+
createColumn: <TData extends RowData, TValue>(
122+
column: Column<TData, TValue>,
123123
table: Table<TData>
124124
): void => {
125125
column.getCanGlobalFilter = () => {

packages/table-core/src/types.ts

Lines changed: 23 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -98,14 +98,20 @@ import { CellContext, CoreCell } from './core/cell'
9898
import { CoreColumn } from './core/column'
9999

100100
export interface TableFeature<TData extends RowData = any> {
101-
createCell?: (
102-
cell: Cell<TData, unknown>,
103-
column: Column<TData>,
101+
createCell?: <TValue>(
102+
cell: Cell<TData, TValue>,
103+
column: Column<TData, TValue>,
104104
row: Row<TData>,
105105
table: Table<TData>
106106
) => void
107-
createColumn?: (column: Column<TData, unknown>, table: Table<TData>) => void
108-
createHeader?: (header: Header<TData, unknown>, table: Table<TData>) => void
107+
createColumn?: <TValue>(
108+
column: Column<TData, TValue>,
109+
table: Table<TData>
110+
) => void
111+
createHeader?: <TValue>(
112+
header: Header<TData, TValue>,
113+
table: Table<TData>
114+
) => void
109115
createRow?: (row: Row<TData>, table: Table<TData>) => void
110116
createTable?: (table: Table<TData>) => void
111117
getDefaultColumnDef?: () => Partial<ColumnDef<TData, unknown>>
@@ -224,7 +230,7 @@ export interface RowModel<TData extends RowData> {
224230
rowsById: Record<string, Row<TData>>
225231
}
226232

227-
export type AccessorFn<TData extends RowData, TValue = unknown> = (
233+
export type AccessorFn<in TData extends RowData, out TValue = unknown> = (
228234
originalRow: TData,
229235
index: number
230236
) => TValue
@@ -253,7 +259,7 @@ type ColumnIdentifiers<TData extends RowData, TValue> =
253259

254260
//
255261

256-
interface ColumnDefExtensions<TData extends RowData, TValue = unknown>
262+
interface ColumnDefExtensions<in out TData extends RowData, in out TValue = unknown>
257263
extends VisibilityColumnDef,
258264
ColumnPinningColumnDef,
259265
ColumnFiltersColumnDef<TData>,
@@ -262,7 +268,7 @@ interface ColumnDefExtensions<TData extends RowData, TValue = unknown>
262268
GroupingColumnDef<TData, TValue>,
263269
ColumnSizingColumnDef {}
264270

265-
export interface ColumnDefBase<TData extends RowData, TValue = unknown>
271+
export interface ColumnDefBase<in out TData extends RowData, in out TValue = unknown>
266272
extends ColumnDefExtensions<TData, TValue> {
267273
getUniqueValues?: AccessorFn<TData, unknown[]>
268274
footer?: ColumnDefTemplate<HeaderContext<TData, TValue>>
@@ -272,7 +278,7 @@ export interface ColumnDefBase<TData extends RowData, TValue = unknown>
272278

273279
//
274280

275-
export interface IdentifiedColumnDef<TData extends RowData, TValue = unknown>
281+
export interface IdentifiedColumnDef<in out TData extends RowData, in out TValue = unknown>
276282
extends ColumnDefBase<TData, TValue> {
277283
id?: string
278284
header?: StringOrTemplateHeader<TData, TValue>
@@ -283,7 +289,7 @@ export type DisplayColumnDef<
283289
TValue = unknown,
284290
> = ColumnDefBase<TData, TValue> & ColumnIdentifiers<TData, TValue>
285291

286-
interface GroupColumnDefBase<TData extends RowData, TValue = unknown>
292+
interface GroupColumnDefBase<in out TData extends RowData, in out TValue = unknown>
287293
extends ColumnDefBase<TData, TValue> {
288294
columns?: ColumnDef<TData, any>[]
289295
}
@@ -294,8 +300,8 @@ export type GroupColumnDef<
294300
> = GroupColumnDefBase<TData, TValue> & ColumnIdentifiers<TData, TValue>
295301

296302
export interface AccessorFnColumnDefBase<
297-
TData extends RowData,
298-
TValue = unknown,
303+
in out TData extends RowData,
304+
in out TValue = unknown,
299305
> extends ColumnDefBase<TData, TValue> {
300306
accessorFn: AccessorFn<TData, TValue>
301307
}
@@ -306,8 +312,8 @@ export type AccessorFnColumnDef<
306312
> = AccessorFnColumnDefBase<TData, TValue> & ColumnIdentifiers<TData, TValue>
307313

308314
export interface AccessorKeyColumnDefBase<
309-
TData extends RowData,
310-
TValue = unknown,
315+
in out TData extends RowData,
316+
in out TValue = unknown,
311317
> extends ColumnDefBase<TData, TValue> {
312318
id?: string
313319
accessorKey: (string & {}) | keyof TData
@@ -337,7 +343,7 @@ export type ColumnDefResolved<
337343
accessorKey?: string
338344
}
339345

340-
export interface Column<TData extends RowData, TValue = unknown>
346+
export interface Column<in out TData extends RowData, in out TValue = unknown>
341347
extends CoreColumn<TData, TValue>,
342348
ColumnVisibilityColumn,
343349
ColumnPinningColumn,
@@ -349,11 +355,11 @@ export interface Column<TData extends RowData, TValue = unknown>
349355
ColumnSizingColumn,
350356
ColumnOrderColumn {}
351357

352-
export interface Cell<TData extends RowData, TValue>
358+
export interface Cell<in out TData extends RowData, in out TValue>
353359
extends CoreCell<TData, TValue>,
354360
GroupingCell {}
355361

356-
export interface Header<TData extends RowData, TValue>
362+
export interface Header<in out TData extends RowData, in out TValue>
357363
extends CoreHeader<TData, TValue>,
358364
ColumnSizingHeader {}
359365

0 commit comments

Comments
 (0)