Skip to content

Commit

Permalink
Fix: type support for suspense and fallbackData(#2396) (#2452)
Browse files Browse the repository at this point in the history
* fix SWROptions type

* add undefined to config type

* fix typo

* add test case for suspense

* add test case for fallbackdata

* add test case for config is undefined

---------

Co-authored-by: taro <taro.onishi@shelfy.jp>
  • Loading branch information
taro-28 and taro-28 committed Feb 24, 2023
1 parent e5b5499 commit 04df1bf
Show file tree
Hide file tree
Showing 2 changed files with 92 additions and 19 deletions.
28 changes: 12 additions & 16 deletions _internal/types.ts
Expand Up @@ -232,27 +232,23 @@ export interface SWRHook {
SWRKey extends Key = StrictKey,
SWROptions extends
| SWRConfiguration<Data, Error, Fetcher<Data, SWRKey>>
| undefined =
| SWRConfiguration<Data, Error, Fetcher<Data, SWRKey>>
| undefined
| undefined = SWRConfiguration<Data, Error, Fetcher<Data, SWRKey>>
>(
key: SWRKey,
config: SWROptions
): SWRResponse<Data, Error, SWROptions>
config: SWROptions | undefined
): SWRResponse<Data, Error, Required<SWROptions>>
<
Data = any,
Error = any,
SWRKey extends Key = StrictKey,
SWROptions extends
| SWRConfiguration<Data, Error, Fetcher<Data, SWRKey>>
| undefined =
| SWRConfiguration<Data, Error, Fetcher<Data, SWRKey>>
| undefined
| undefined = SWRConfiguration<Data, Error, Fetcher<Data, SWRKey>>
>(
key: SWRKey,
fetcher: Fetcher<Data, SWRKey> | null,
config: SWROptions
): SWRResponse<Data, Error, SWROptions>
config: SWROptions | undefined
): SWRResponse<Data, Error, Required<SWROptions>>
<Data = any, Error = any>(key: Key): SWRResponse<Data, Error>
<Data = any, Error = any>(
key: Key,
Expand All @@ -263,22 +259,22 @@ export interface SWRHook {
Error = any,
SWROptions extends
| SWRConfiguration<Data, Error, BareFetcher<Data>>
| undefined = SWRConfiguration<Data, Error, BareFetcher<Data>> | undefined
| undefined = SWRConfiguration<Data, Error, BareFetcher<Data>>
>(
key: Key,
config: SWROptions
): SWRResponse<Data, Error, SWROptions>
config: SWROptions | undefined
): SWRResponse<Data, Error, Required<SWROptions>>
<
Data = any,
Error = any,
SWROptions extends
| SWRConfiguration<Data, Error, BareFetcher<Data>>
| undefined = SWRConfiguration<Data, Error, BareFetcher<Data>> | undefined
| undefined = SWRConfiguration<Data, Error, BareFetcher<Data>>
>(
key: Key,
fetcher: BareFetcher<Data> | null,
config: SWROptions
): SWRResponse<Data, Error, SWROptions>
config: SWROptions | undefined
): SWRResponse<Data, Error, Required<SWROptions>>
}

// Middleware guarantees that a SWRHook receives a key, fetcher, and config as the argument
Expand Down
83 changes: 80 additions & 3 deletions test/type/config.tsx
Expand Up @@ -2,7 +2,11 @@ import React from 'react'
import type { Cache, SWRResponse } from 'swr'
import useSWR, { useSWRConfig, SWRConfig } from 'swr'
import { expectType } from './utils'
import type { FullConfiguration } from 'swr/_internal'
import type {
BareFetcher,
FullConfiguration,
PublicConfiguration
} from 'swr/_internal'
import type { Equal } from '@type-challenges/utils'

export function testCache() {
Expand Down Expand Up @@ -53,13 +57,45 @@ export function testSWRResponseCachedDataTypes() {
}

export function testSuspense() {
const { data: suspenseyData } = useSWR(
// 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)

// Generics
const { data: data3 } = useSWR<string>(
'/api',
(k: string) => Promise.resolve(k),
{ suspense: true }
)
expectType<string>(data3)

// Generics(default fetcher)
const { data: data4 } = useSWR<string>('/api', { suspense: true })
expectType<string>(data4)

// Generics(SWRKey)
const { data: data5 } = useSWR<string, any, '/api'>(
'/api',
(k: string) => Promise.resolve(k),
{
suspense: true
}
)
expectType<string>(data5)

expectType<string>(suspenseyData)
// Generics(SWRKey, default fetcher)
const { data: data6 } = useSWR<string, any, '/api'>('/api', {
suspense: true
})
expectType<string>(data6)
}

export function testFallbackData() {
Expand All @@ -86,4 +122,45 @@ export function testFallbackData() {
fallbackData: { value: 'fallback' }
})
expectType<{ value: string }>(data3)

// Does not need specific fetcher

// Basic(default fetcher)
const { data: data4 } = useSWR('/api', { fallbackData: 'fallback' })
expectType<any>(data4)

// Generics
const { data: data5 } = useSWR<string>(
'/api',
(k: string) => Promise.resolve(k),
{ fallbackData: 'fallback' }
)
expectType<string>(data5)

// Generics(default fetcher)
const { data: data6 } = useSWR<string>('/api', { fallbackData: 'fallback' })
expectType<string>(data6)

// Generics(SWRKey)
const { data: data7 } = useSWR<string, any, '/api'>(
'/api',
(k: string) => Promise.resolve(k),
{ fallbackData: 'fallback' }
)
expectType<string>(data7)

// Generics(SWRKey, default fetcher)
const { data: data8 } = useSWR<string, any, '/api'>('/api', {
fallbackData: 'fallback'
})
expectType<string>(data8)
}
export function testUndefined() {
// Undefined can be passed to config.
expectType<
Equal<
Parameters<typeof useSWR<string, any>>['2'],
Partial<PublicConfiguration<string, any, BareFetcher<string>>> | undefined
>
>(true)
}

0 comments on commit 04df1bf

Please sign in to comment.