config.tsx
Overview
The config.tsx file serves as a comprehensive test and demonstration suite for the type safety, configuration, and usage patterns of the SWR React Hooks library, specifically focusing on its configuration system (SWRConfig), caching, fallback data, suspense mode, and type inference behaviors.
Rather than providing runtime features directly, this file primarily contains TypeScript type tests and React component snippets that verify the correct typing of SWR hooks and configurations across various use cases. The tests use expectType assertions to ensure type correctness and demonstrate best practices or limitations of SWR's API with TypeScript.
The file is especially useful for library authors, maintainers, or advanced users who want to understand or verify how SWR’s generic types, configuration options, and data fetching hooks interact in complex scenarios.
Detailed Explanations
Imported Modules and Types
useSWR,useSWRConfig,SWRConfig(from'swr'): Core hooks and context provider for SWR data fetching.Cache,SWRResponse(types from'swr'): Type definitions for cache and hook response.FullConfiguration,SWRConfiguration(from'swr/_internal'): Internal and full configuration types for SWR.expectType(from'./utils'): Utility to assert TypeScript types at compile time.Equal(from'@type-challenges/utils'): Type utility to test type equality.
Functions
Each exported function tests or demonstrates a specific aspect of SWR configuration or usage.
testCache()
Purpose: Asserts that the cache from
useSWRConfig()is of typeCache<any>.Details: Calls
expectTypewith the cache type to verify.
export function testCache() {
expectType<Cache<any>>(useSWRConfig().cache)
}
Usage: Ensures the global cache object from configuration has the correct type.
testCustomSWRConfig()
Purpose: Demonstrates valid and invalid values for
SWRConfig'svalueprop.Details: Shows that
nullor functions returningnullcause TypeScript errors, whileundefined, objects, and valid fallbacks are accepted.
export function testCustomSWRConfig() {
const noNull = [
// @ts-expect-error
<SWRConfig key={'null'} value={null} />,
// @ts-expect-error
<SWRConfig key={'callback-return-null'} value={() => null} />
]
return (
<>
{noNull}
<SWRConfig value={undefined} />
<SWRConfig value={() => ({})} />
<SWRConfig
value={{
fallback: {
'/api': 'fallback',
'/api2': Promise.resolve('fallback2')
}
}}
/>
<SWRConfig
// @ts-expect-error
value={() => 0}
/>
</>
)
}
Usage: Useful for validating configuration values in SWR context provider.
testFullConfiguration()
Purpose: Validates type inference for
FullConfigurationgeneric with data and error types.Parameters: None.
Returns: Void.
Details: Checks that the
fallbackDataproperty of the default configuration can accept a data value, promise, or undefined.
export function testFullConfiguration() {
type IData = { value: string }
type IError = { error: any }
type IConfig = FullConfiguration<IData, IError>
const config: IConfig = SWRConfig.defaultValue
expectType<IData | Promise<IData> | undefined>(config.fallbackData)
}
Usage: Ensures correct typing of full SWR configuration objects.
testSWRResponseCachedDataTypes()
Purpose: Tests the data type returned by
useSWRwhen used with suspense mode enabled.Details: Checks that
datais correctly typed when suspense is true and with conditional generics.
export function testSWRResponseCachedDataTypes() {
type FilledData = SWRResponse<string, any, { suspense: true }>['data']
expectType<Equal<FilledData, string>>(true)
type FilledConditionalData = SWRResponse<
string | number,
any,
{ suspense: true }
>['data']
expectType<Equal<FilledConditionalData, string | number>>(true)
}
Usage: Ensures that suspense mode correctly infers data types from SWR responses.
testSuspense()
Purpose: Demonstrates use of
useSWRwith suspense enabled, showing type inference nuances.Details: Covers multiple cases including default fetchers, explicit generics, and their impact on inferred data types.
export function testSuspense() {
// Basic
const { data: data1 } = useSWR('/api', (k: string) => Promise.resolve(k), {
suspense: true
})
expectType<string>(data1)
// Basic(default fetcher)
const { data: data2 } = useSWR('/api', {
suspense: true
})
expectType<any>(data2)
// Explicit generics lose partial inference
const { data: data3 } = useSWR<string>(
'/api',
(k: string) => Promise.resolve(k),
{ suspense: true }
)
expectType<string | undefined>(data3)
const { data: data4 } = useSWR<string, any, { suspense: true }>(
'/api',
(k: string) => Promise.resolve(k),
{ suspense: true }
)
expectType<string>(data4)
}
Usage: Guides developers on how to correctly type suspense-enabled SWR hooks.
testFallbackData()
Purpose: Tests various fallbackData scenarios with
useSWRto verify type inference.Details: Covers simple types, conditional types, complex objects, promises, and cases with or without explicit fetchers or generics.
export function testFallbackData() {
// Basic
const fetcher1 = (k: string) => Promise.resolve(k)
const { data: data1 } = useSWR('/api', fetcher1, {
fallbackData: 'fallback'
})
expectType<string>(data1)
// Conditional
const fetcher2 = (k: string) =>
Promise.resolve(Math.random() > 0.5 ? k : Math.random() * 100)
const { data: data2 } = useSWR('/api', fetcher2, {
fallbackData: 'fallback'
})
expectType<string | number>(data2)
// Complex
const fetcher3 = (k: string) => Promise.resolve({ value: k })
const { data: data3 } = useSWR('/api', fetcher3, {
fallbackData: { value: 'fallback' }
})
expectType<{ value: string }>(data3)
// Without specific fetcher
const { data: data4 } = useSWR('/api', { fallbackData: 'fallback' })
expectType<any>(data4)
// Explicit generics and fallbackData combinations
const { data: data5 } = useSWR<string>(
'/api',
(k: string) => Promise.resolve(k),
{ fallbackData: 'fallback' }
)
expectType<string | undefined>(data5)
const { data: data6 } = useSWR<string, any, { fallbackData: 'fallback' }>(
'/api',
(k: string) => Promise.resolve(k),
{ fallbackData: 'fallback' }
)
expectType<string>(data6)
// Promise fallbackData
const { data: data7 } = useSWR<
string,
any,
{ fallbackData: Promise<'fallback'> }
>('/api', (k: string) => Promise.resolve(k), {
fallbackData: Promise.resolve('fallback')
})
expectType<string>(data7)
// Declaring fallbackData exists in config
const { data: data8 } = useSWR<string, any, { fallbackData: string }>('/api')
const { data: data9 } = useSWR<string, any, { fallbackData: string }>(
'/api',
{}
)
expectType<string>(data8)
expectType<string>(data9)
}
Usage: Provides a thorough reference on how fallbackData affects SWR's data type inference.
testConfigAsSWRConfiguration()
Purpose: Tests that passing an empty object cast as
SWRConfigurationas config works correctly.
export function testConfigAsSWRConfiguration() {
const fetcher = (k: string) => Promise.resolve({ value: k })
const { data } = useSWR('/api', fetcher, {} as SWRConfiguration)
expectType<Equal<typeof data, { value: string } | undefined>>(true)
}
Usage: Useful for ensuring type compatibility when explicitly casting config.
testEmptyConfig()
Purpose: Confirms that an empty SWR config still infers correct types for
data,error, andisLoading.
export function testEmptyConfig() {
const fetcher = (k: string) => Promise.resolve({ value: k })
const { data, error, isLoading } = useSWR<{ value: string }, Error>(
'/api',
fetcher,
{}
)
expectType<Equal<typeof data, { value: string } | undefined>>(true)
expectType<Equal<typeof error, Error | undefined>>(true)
expectType<Equal<typeof isLoading, boolean>>(true)
}
Usage: Shows default SWR states and typings.
testFallbackDataConfig()
Purpose: Tests that fallbackData in config enforces non-undefined data type.
export function testFallbackDataConfig() {
const fetcher = (k: string) => Promise.resolve({ value: k })
const { data, isLoading } = useSWR('/api', fetcher, {
fallbackData: { value: 'fallback' }
})
expectType<Equal<typeof data, { value: string }>>(true)
expectType<Equal<typeof isLoading, boolean>>(true)
}
Usage: Demonstrates that fallbackData removes undefined from data type.
testProviderConfig()
Purpose: Demonstrates how to provide a custom SWR configuration via the
SWRConfigcontext provider.Parameters:
children(ReactNode) - child components wrapped by the provider.Returns: React component wrapping children with custom SWR config.
Details: Customizes provider, online/visibility state detectors, and event init functions.
export function testProviderConfig() {
const GlobalSetting = ({ children }: { children: React.ReactNode }) => {
return (
<SWRConfig
value={{
provider: () => new Map(),
isOnline() {
/* Customize the network state detector */
return true
},
isVisible() {
/* Customize the visibility state detector */
return true
},
initFocus(_callback) {
/* Register the listener with your state provider */
},
initReconnect(_callback) {
/* Register the listener with your state provider */
}
}}
>
{children}
</SWRConfig>
)
}
return (
<GlobalSetting>
<div />
</GlobalSetting>
)
}
Usage: Shows how to globally customize SWR's behavior in a React app.
Important Implementation Details
The file uses TypeScript's
@ts-expect-errorcomments to intentionally test invalid types and verify that TypeScript catches such errors.Usage of utility types like
EqualandexpectTypeallow compile-time assertions without impacting runtime.The file extensively tests generic type inference behavior of SWR hooks, especially how explicit generics can affect inference (notably with Suspense and fallback data).
It demonstrates how SWR’s
SWRConfigprovider can be customized to replace internal mechanisms like cache provider or event listeners.
Interaction with Other Parts of the System
This file imports from
swrand related internal modules, so it depends on SWR’s implementation and type definitions.It imports
expectTypefrom a localutilsmodule, presumably a helper for compile-time type assertions.The file is meant for development, testing, or documentation purposes rather than production runtime.
It interacts with React by rendering
SWRConfigcomponents and testing React hooks.It supports SWR’s type system validation and assists in maintaining type safety in the broader application or library.
Visual Diagram: Component and Function Relationships
flowchart TD
subgraph SWRConfig Provider Tests
A[testCustomSWRConfig()]
B[testProviderConfig()]
end
subgraph SWR Hook Usage Tests
C[testSuspense()]
D[testFallbackData()]
E[testConfigAsSWRConfiguration()]
F[testEmptyConfig()]
G[testFallbackDataConfig()]
H[testSWRResponseCachedDataTypes()]
end
subgraph Type Utilities
I[testCache()]
J[testFullConfiguration()]
end
A --> B
C --> H
D --> H
E --> F
F --> G
I --> J
Explanation:
testCustomSWRConfigandtestProviderConfigrelate toSWRConfigand its props/usage as a React provider.The main SWR hooks usage tests (
testSuspense,testFallbackData, etc.) focus on different config options and their impact on hook data types.testCacheandtestFullConfigurationare utilities to verify core SWR types.
Usage Summary
This file is primarily intended to:
Validate SWR type safety with TypeScript for internal development and contributors.
Serve as a reference for developers on how to configure SWR and how generics affect type inference.
Demonstrate correct and incorrect usages of SWR configuration and hooks.
Document subtle behaviors (e.g., suspense mode, fallbackData) through code examples with type assertions.