types.ts
Overview
The types.ts file defines TypeScript types, interfaces, and type aliases essential for the infinite loading feature in the SWR (stale-while-revalidate) data fetching library ecosystem. It provides precise typings for the infinite loading hook (useSWRInfinite), its configuration options, fetchers, responses, mutation behaviors, and cache state extensions.
This file is purely about type declarations and does not contain runtime logic or implementations. Its purpose is to enforce strong type safety, provide clear API contracts, and enable rich developer experience (including autocomplete and compile-time checks) when working with paginated or infinite data fetching scenarios.
Detailed Explanation of Types and Interfaces
Core Type Aliases and Interfaces
FetcherResponse<Data = unknown>
type FetcherResponse<Data = unknown> = Data | Promise<Data>
Represents the return type of a fetcher function, which can be either synchronous data (
Data) or a Promise resolving toData.Used internally by fetcher types.
SWRInfiniteKeyLoader<Data = any, Args extends Arguments = Arguments>
export type SWRInfiniteKeyLoader<
Data = any,
Args extends Arguments = Arguments
> = (index: number, previousPageData: Data | null) => Args
Purpose: Function generating the key (arguments) used to fetch a specific page in infinite loading.
Parameters:
index: The zero-based page index (e.g., 0 for the first page).previousPageData: Data from the previous page, ornullif no previous page.
Returns:
Args— the key arguments used by the fetcher.Usage Example:
const getKey: SWRInfiniteKeyLoader<User[]> = (pageIndex, previousPageData) => {
if (previousPageData && !previousPageData.length) return null; // No more pages
return ['api/users', pageIndex];
};
SWRInfiniteFetcher<Data, KeyLoader>
export type SWRInfiniteFetcher<
Data = any,
KeyLoader extends SWRInfiniteKeyLoader = SWRInfiniteKeyLoader
> = KeyLoader extends (...args: any[]) => any
? ReturnType<KeyLoader> extends infer T | null | false | undefined
? (args: T) => FetcherResponse<Data>
: never
: never
Purpose: Type of the fetcher function used by
useSWRInfinite.Details:
The fetcher accepts arguments returned by the key loader (
T).Returns
Dataor a Promise ofData.If the key loader returns a falsy value (
null,false,undefined), the fetcher is never called.
Usage Example:
const fetcher: SWRInfiniteFetcher<User[], typeof getKey> = ([url, page]) =>
fetch(`${url}?page=${page}`).then(res => res.json());
SWRInfiniteCompareFn<Data>
export interface SWRInfiniteCompareFn<Data = any> {
(a: Data | undefined, b: Data | undefined): boolean
(a: Data[] | undefined, b: Data[] | undefined): boolean
}
Function signature for comparing two page data sets or arrays of page data to determine equality.
Used to optimize re-renders by shallow or deep comparison.
Returns
trueif equal,falseotherwise.
SWRInfiniteConfiguration<Data, Error, Fn>
export interface SWRInfiniteConfiguration<
Data = any,
Error = any,
Fn extends SWRInfiniteFetcher<Data> = BareFetcher<Data>
> extends Omit<SWRConfiguration<Data[], Error>, 'compare'> {
initialSize?: number
revalidateAll?: boolean
persistSize?: boolean
revalidateFirstPage?: boolean
parallel?: boolean
fetcher?: Fn
compare?: SWRInfiniteCompareFn<Data>
}
Extends the core SWR configuration with infinite-loading-specific options:
initialSize: Number of pages to load initially (default typically 1).revalidateAll: Whether to revalidate all pages on revalidation.persistSize: Whether to keep the page size persisted across renders.revalidateFirstPage: Whether to always revalidate the first page.parallel: Whether to fetch pages in parallel (default is sequential).fetcher: Custom fetcher function of typeFn.compare: Custom compare function for page data arrays.
Inherits other standard SWR config options like
onError,dedupingInterval, etc.
SWRInfiniteRevalidateFn<Data>
interface SWRInfiniteRevalidateFn<Data = any> {
(data: Data, key: Arguments): boolean
}
A function deciding whether a page should be revalidated given its current data and key arguments.
Returns a boolean indicating whether to revalidate.
SWRInfiniteKeyedMutator<Data>
export type SWRInfiniteKeyedMutator<Data> = <MutationData = Data>(
data?: Data | Promise<Data | undefined> | MutatorCallback<Data>,
opts?: boolean | SWRInfiniteMutatorOptions<Data, MutationData>
) => Promise<Data | MutationData | undefined>
The mutation function returned by the infinite hook to mutate paginated data.
Supports:
Passing new data directly.
Passing a Promise resolving to data.
Passing a callback that receives current data and returns new data.
Accepts options to control revalidation behavior.
Returns a Promise resolving to the updated data.
SWRInfiniteMutatorOptions<Data, MutationData>
export interface SWRInfiniteMutatorOptions<Data = any, MutationData = Data>
extends Omit<MutatorOptions<Data, MutationData>, 'revalidate'> {
revalidate?:
| boolean
| SWRInfiniteRevalidateFn<Data extends unknown[] ? Data[number] : never>
}
Mutation options extend standard mutator options but override
revalidateto allow:A boolean flag.
A custom function deciding revalidation per page.
Enables fine-grained control over which pages to revalidate after mutation.
SWRInfiniteResponse<Data, Error>
export interface SWRInfiniteResponse<Data = any, Error = any>
extends Omit<SWRResponse<Data[], Error>, 'mutate'> {
size: number
setSize: (
size: number | ((_size: number) => number)
) => Promise<Data[] | undefined>
mutate: SWRInfiniteKeyedMutator<Data[]>
}
Response object returned by the infinite hook.
Extends core SWR response for
Data[](array of page data).Adds:
size: Current number of pages loaded.setSize: Function to update the number of pages to load, triggering fetch or discard.mutate: Mutator function specialized for paginated data.
SWRInfiniteHook
export interface SWRInfiniteHook {
// Overloads supporting:
// - getKey only
// - getKey + fetcher
// - getKey + config
// - getKey + fetcher + config
// with appropriate typings for Data, Error, KeyLoader, fetcher, and config.
}
Represents the typed signature of the infinite loading hook, typically
useSWRInfinite.Supports multiple overloads with different combinations of parameters:
getKeyloader function.Optional
fetcher.Optional
config.
Returns
SWRInfiniteResponsewith typed data and error.Enables flexible usage with strong type inference.
SWRInfiniteCacheValue<Data, Error>
export interface SWRInfiniteCacheValue<Data = any, Error = any>
extends State<Data, Error> {
_i?: boolean // Flag indicating infinite key context
_l?: number // Cached page size (number of pages)
_k?: Arguments // Cached key arguments for the first page
_r?: boolean | SWRInfiniteRevalidateFn // Revalidation flag or function
}
Internal cache state extension used to store infinite-load-specific metadata.
Stored in the global cache under the infinite key.
Fields:
_i: Marks this cache entry as infinite loading context._l: Stores the current page size._k: Stores the key arguments associated with the first page._r: Stores flags or functions controlling revalidation behavior.
Important Implementation Details and Algorithms (Contextual Notes)
Although this file contains only types, the design reflects key infinite-loading mechanisms:
Dynamic Page Keys: The key loader enables paging by generating keys per page index possibly using previous page data (e.g., cursor pagination).
Page Size Management: Page size is tracked in cache (
_l) and exposed assizeandsetSizeAPIs, allowing components to load more or fewer pages dynamically.Parallel vs Sequential Fetching: The
parallelflag in config controls whether page fetches happen concurrently or in sequence.Revalidation Control: Custom compare functions and revalidation flags enable granular control over cache updates and re-fetching.
Mutation Support: Specialized mutator options and
mutatemethod enable efficient updates of paginated data sets.
Interactions with Other System Parts
Internal SWR Types: Imports core SWR types (
SWRConfiguration,SWRResponse,Arguments,BareFetcher,State,StrictTupleKey,MutatorOptions,MutatorCallback) from an internal module (../_internal). This ensures consistency across SWR features.Infinite Loading Middleware & Hook: These types are consumed by the infinite loading implementation (e.g.,
useSWRInfinitehook and its middleware), providing the API surface and type contracts.Cache Provider: The cache value interface extends the global cache state, enabling shared metadata and coordination between infinite loading hook instances.
Fetcher & Key Loader Functions: These types tightly couple the key generation and fetching mechanisms, ensuring that keys and fetchers agree on argument types.
Usage Example (Simplified)
import type { SWRInfiniteKeyLoader, SWRInfiniteFetcher, SWRInfiniteResponse } from './types';
const getKey: SWRInfiniteKeyLoader<User[]> = (pageIndex, previousPageData) => {
if (previousPageData && !previousPageData.length) return null; // End pagination
return [`/api/users?page=${pageIndex}`];
};
const fetcher: SWRInfiniteFetcher<User[]> = (args) => fetch(args[0]).then(res => res.json());
function Component() {
const { data, size, setSize, mutate }: SWRInfiniteResponse<User[]> = useSWRInfinite(getKey, fetcher);
return (
<>
{data?.map((page, i) => (
<UserList key={i} users={page} />
))}
<button onClick={() => setSize(size + 1)}>Load More</button>
</>
);
}
Mermaid Class Diagram: Structure of types.ts
classDiagram
class SWRInfiniteHook {
+getKey: SWRInfiniteKeyLoader
+fetcher?: SWRInfiniteFetcher
+config?: SWRInfiniteConfiguration
+returns SWRInfiniteResponse
}
class SWRInfiniteKeyLoader {
+index: number
+previousPageData: Data | null
+returns Args
}
class SWRInfiniteFetcher {
+args: Args
+returns Data | Promise<Data>
}
class SWRInfiniteConfiguration {
+initialSize: number
+revalidateAll: boolean
+persistSize: boolean
+revalidateFirstPage: boolean
+parallel: boolean
+fetcher: SWRInfiniteFetcher
+compare: SWRInfiniteCompareFn
}
class SWRInfiniteResponse {
+size: number
+setSize(size)
+mutate(data, opts)
}
class SWRInfiniteCacheValue {
+_i: boolean
+_l: number
+_k: Arguments
+_r: boolean | SWRInfiniteRevalidateFn
}
SWRInfiniteHook --> SWRInfiniteKeyLoader : uses
SWRInfiniteHook --> SWRInfiniteFetcher : optionally uses
SWRInfiniteHook --> SWRInfiniteConfiguration : optionally uses
SWRInfiniteHook --> SWRInfiniteResponse : returns
SWRInfiniteResponse --> SWRInfiniteKeyedMutator : mutate type
SWRInfiniteConfiguration --> SWRInfiniteFetcher : fetcher type
Summary
The types.ts file is foundational for the infinite loading feature in SWR, defining comprehensive and flexible typings for:
Dynamic key loaders and fetchers per page.
Configurations extending core SWR with infinite-loading options.
Responses and mutation APIs tailored for paginated data.
Cache state extensions for managing page size and revalidation state.
These types enable robust, type-safe infinite scrolling and pagination patterns with SWR and integrate closely with the core SWR architecture and caching mechanisms. They serve as a contract between the infinite loading implementation, the fetchers, and consumers of the useSWRInfinite hook.