0
# Types and Utilities
1
2
Core type definitions, interfaces, and utility functions used throughout the TanStack React Virtual virtualization system.
3
4
## Capabilities
5
6
### Core Interfaces
7
8
Essential interfaces that define the structure of virtual items and configuration objects.
9
10
```typescript { .api }
11
/**
12
* Represents a virtualized item with position and size information
13
*/
14
export interface VirtualItem {
15
/** Unique key for the item (from getItemKey function) */
16
key: Key;
17
/** Zero-based index of the item in the data array */
18
index: number;
19
/** Start position of the item in pixels from the beginning of the scroll area */
20
start: number;
21
/** End position of the item in pixels from the beginning of the scroll area */
22
end: number;
23
/** Height (vertical) or width (horizontal) of the item in pixels */
24
size: number;
25
/** Lane number for grid layouts (0-based) */
26
lane: number;
27
}
28
29
/**
30
* Represents the dimensions of a rectangular area
31
*/
32
export interface Rect {
33
/** Width in pixels */
34
width: number;
35
/** Height in pixels */
36
height: number;
37
}
38
39
/**
40
* Defines a range of items with overscan information
41
*/
42
export interface Range {
43
/** Index of the first item in the range */
44
startIndex: number;
45
/** Index of the last item in the range */
46
endIndex: number;
47
/** Number of items to render outside the visible area */
48
overscan: number;
49
/** Total number of items in the dataset */
50
count: number;
51
}
52
53
/**
54
* Options for scrolling operations
55
*/
56
export interface ScrollToOptions {
57
/** How to align the target within the viewport */
58
align?: ScrollAlignment;
59
/** Scroll behavior (smooth or instant) */
60
behavior?: ScrollBehavior;
61
}
62
```
63
64
### Type Aliases
65
66
Common type aliases used throughout the virtualization system.
67
68
```typescript { .api }
69
/**
70
* Valid key types for identifying virtual items
71
*/
72
export type Key = number | string | bigint;
73
74
/**
75
* Direction of scroll movement
76
*/
77
export type ScrollDirection = 'forward' | 'backward';
78
79
/**
80
* How to align items when scrolling
81
*/
82
export type ScrollAlignment = 'start' | 'center' | 'end' | 'auto';
83
84
/**
85
* Browser scroll behavior
86
*/
87
export type ScrollBehavior = 'auto' | 'smooth';
88
89
/**
90
* Options for scrollToOffset method
91
*/
92
export type ScrollToOffsetOptions = ScrollToOptions;
93
94
/**
95
* Options for scrollToIndex method
96
*/
97
export type ScrollToIndexOptions = ScrollToOptions;
98
```
99
100
### Observer Functions
101
102
Functions for observing element and window changes, used internally by the virtualization engine.
103
104
```typescript { .api }
105
/**
106
* Observe changes to an element's dimensions using ResizeObserver
107
* @param instance - Virtualizer instance
108
* @param cb - Callback function to receive dimension updates
109
* @returns Cleanup function to stop observing
110
*/
111
export function observeElementRect<T extends Element>(
112
instance: Virtualizer<T, any>,
113
cb: (rect: Rect) => void
114
): void | (() => void);
115
116
/**
117
* Observe changes to window dimensions
118
* @param instance - Virtualizer instance for window
119
* @param cb - Callback function to receive dimension updates
120
* @returns Cleanup function to stop observing
121
*/
122
export function observeWindowRect(
123
instance: Virtualizer<Window, any>,
124
cb: (rect: Rect) => void
125
): void | (() => void);
126
127
/**
128
* Observe scroll offset changes for an element
129
* @param instance - Virtualizer instance
130
* @param cb - Callback function to receive offset and scrolling state
131
* @returns Cleanup function to stop observing
132
*/
133
export function observeElementOffset<T extends Element>(
134
instance: Virtualizer<T, any>,
135
cb: (offset: number, isScrolling: boolean) => void
136
): void | (() => void);
137
138
/**
139
* Observe scroll offset changes for the window
140
* @param instance - Virtualizer instance for window
141
* @param cb - Callback function to receive offset and scrolling state
142
* @returns Cleanup function to stop observing
143
*/
144
export function observeWindowOffset(
145
instance: Virtualizer<Window, any>,
146
cb: (offset: number, isScrolling: boolean) => void
147
): void | (() => void);
148
```
149
150
### Scroll Functions
151
152
Functions that handle scrolling for different element types.
153
154
```typescript { .api }
155
/**
156
* Scroll function for DOM elements
157
* @param offset - Target scroll position in pixels
158
* @param options - Scroll options with adjustments and behavior
159
* @param instance - Virtualizer instance
160
*/
161
export function elementScroll<T extends Element>(
162
offset: number,
163
options: { adjustments?: number; behavior?: ScrollBehavior },
164
instance: Virtualizer<T, any>
165
): void;
166
167
/**
168
* Scroll function for the window
169
* @param offset - Target scroll position in pixels
170
* @param options - Scroll options with adjustments and behavior
171
* @param instance - Virtualizer instance
172
*/
173
export function windowScroll<T extends Window>(
174
offset: number,
175
options: { adjustments?: number; behavior?: ScrollBehavior },
176
instance: Virtualizer<T, any>
177
): void;
178
```
179
180
### Measurement Functions
181
182
Functions for measuring and calculating item sizes.
183
184
```typescript { .api }
185
/**
186
* Measure the size of a DOM element
187
* @param element - Element to measure
188
* @param entry - ResizeObserver entry (optional)
189
* @param instance - Virtualizer instance
190
* @returns Size in pixels (height for vertical, width for horizontal)
191
*/
192
export function measureElement<TItemElement extends Element>(
193
element: TItemElement,
194
entry: ResizeObserverEntry | undefined,
195
instance: Virtualizer<any, TItemElement>
196
): number;
197
```
198
199
### Default Functions
200
201
Default implementation functions that can be customized.
202
203
```typescript { .api }
204
/**
205
* Default key extraction function
206
* @param index - Item index
207
* @returns The index as the key
208
*/
209
export function defaultKeyExtractor(index: number): number;
210
211
/**
212
* Default range extraction function that includes overscan
213
* @param range - Range specification with overscan
214
* @returns Array of indexes to render
215
*/
216
export function defaultRangeExtractor(range: Range): Array<number>;
217
```
218
219
**Usage Examples:**
220
221
```typescript
222
import { defaultRangeExtractor, Range } from '@tanstack/react-virtual';
223
224
// Custom range extractor that limits overscan
225
function limitedRangeExtractor(range: Range): Array<number> {
226
const maxOverscan = 5;
227
const actualOverscan = Math.min(range.overscan, maxOverscan);
228
229
return defaultRangeExtractor({
230
...range,
231
overscan: actualOverscan
232
});
233
}
234
235
// Custom key extractor for complex data
236
function dataKeyExtractor(index: number): string {
237
return `item-${data[index]?.id ?? index}`;
238
}
239
```
240
241
### Utility Functions
242
243
General utility functions used throughout the library.
244
245
```typescript { .api }
246
/**
247
* Assert that a value is not undefined
248
* @param value - Value to check
249
* @param msg - Optional error message
250
* @returns The value if not undefined
251
* @throws Error if value is undefined
252
*/
253
export function notUndefined<T>(value: T | undefined, msg?: string): T;
254
255
/**
256
* Check if two numbers are approximately equal (within 1.01 pixels)
257
* @param a - First number
258
* @param b - Second number
259
* @returns True if approximately equal
260
*/
261
export function approxEqual(a: number, b: number): boolean;
262
263
/**
264
* Create a debounced version of a function
265
* @param targetWindow - Window object for setTimeout/clearTimeout
266
* @param fn - Function to debounce
267
* @param ms - Debounce delay in milliseconds
268
* @returns Debounced function
269
*/
270
export function debounce(
271
targetWindow: Window & typeof globalThis,
272
fn: Function,
273
ms: number
274
): Function;
275
276
/**
277
* Memoization utility with dependency tracking
278
* @param getDeps - Function that returns current dependencies
279
* @param fn - Function to memoize
280
* @param opts - Memoization options
281
* @returns Memoized function with updateDeps method
282
*/
283
export function memo<TDeps extends ReadonlyArray<any>, TResult>(
284
getDeps: () => [...TDeps],
285
fn: (...args: NoInfer<[...TDeps]>) => TResult,
286
opts: {
287
key: false | string;
288
debug?: () => boolean;
289
onChange?: (result: TResult) => void;
290
initialDeps?: TDeps;
291
}
292
): (() => TResult) & { updateDeps: (newDeps: [...TDeps]) => void };
293
```
294
295
### Utility Types
296
297
Advanced TypeScript utility types for better type safety.
298
299
```typescript { .api }
300
/**
301
* Type that prevents TypeScript from inferring generic types
302
*/
303
export type NoInfer<A extends any> = [A][A extends any ? 0 : never];
304
305
/**
306
* Make specific keys of an interface optional while keeping others required
307
*/
308
export type PartialKeys<T, K extends keyof T> = Omit<T, K> & Partial<Pick<T, K>>;
309
```
310
311
**Usage Examples:**
312
313
```typescript
314
import { PartialKeys, VirtualizerOptions } from '@tanstack/react-virtual';
315
316
// Example of PartialKeys usage - make some required options optional
317
type SimplifiedOptions<TScrollElement extends Element, TItemElement extends Element> =
318
PartialKeys<
319
VirtualizerOptions<TScrollElement, TItemElement>,
320
'observeElementRect' | 'observeElementOffset' | 'scrollToFn'
321
>;
322
323
// This allows creating options objects without providing the complex observer functions
324
const options: SimplifiedOptions<HTMLDivElement, HTMLDivElement> = {
325
count: 1000,
326
getScrollElement: () => document.getElementById('container') as HTMLDivElement,
327
estimateSize: () => 50,
328
// observeElementRect, observeElementOffset, and scrollToFn are now optional
329
};
330
```
331
332
## Common Usage Patterns
333
334
### Custom Key Extraction
335
336
```typescript
337
import { useVirtualizer } from '@tanstack/react-virtual';
338
339
interface DataItem {
340
id: string;
341
name: string;
342
}
343
344
function CustomKeyList({ items }: { items: DataItem[] }) {
345
const virtualizer = useVirtualizer({
346
count: items.length,
347
getScrollElement: () => parentRef.current,
348
estimateSize: () => 50,
349
getItemKey: (index) => items[index]?.id ?? index,
350
});
351
352
return (
353
// Virtual list implementation
354
);
355
}
356
```
357
358
### Custom Range Extraction
359
360
```typescript
361
import { useVirtualizer, defaultRangeExtractor, Range } from '@tanstack/react-virtual';
362
363
// Custom range extractor that adds extra items at the end
364
function extraEndRangeExtractor(range: Range): Array<number> {
365
const defaultIndexes = defaultRangeExtractor(range);
366
367
// Add 5 extra items at the end if we're near the bottom
368
if (range.endIndex >= range.count - 10) {
369
const extraItems = Math.min(5, range.count - 1 - range.endIndex);
370
for (let i = 1; i <= extraItems; i++) {
371
if (range.endIndex + i < range.count) {
372
defaultIndexes.push(range.endIndex + i);
373
}
374
}
375
}
376
377
return defaultIndexes;
378
}
379
380
function CustomRangeList({ items }: { items: any[] }) {
381
const virtualizer = useVirtualizer({
382
count: items.length,
383
getScrollElement: () => parentRef.current,
384
estimateSize: () => 50,
385
rangeExtractor: extraEndRangeExtractor,
386
});
387
388
return (
389
// Virtual list implementation
390
);
391
}
392
```
393
394
### Debug Mode Usage
395
396
```typescript
397
import { useVirtualizer } from '@tanstack/react-virtual';
398
399
function DebugVirtualList({ items }: { items: any[] }) {
400
const virtualizer = useVirtualizer({
401
count: items.length,
402
getScrollElement: () => parentRef.current,
403
estimateSize: () => 50,
404
debug: process.env.NODE_ENV === 'development',
405
});
406
407
// Debug mode will log performance metrics to console
408
409
return (
410
// Virtual list implementation
411
);
412
}
413
```