Skip to content

Commit 435604c

Browse files
authored
types: makes types fn and config and getKey more strictly (#946)
1 parent 5e82bb6 commit 435604c

File tree

4 files changed

+57
-70
lines changed

4 files changed

+57
-70
lines changed

src/swr-config-context.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { createContext } from 'react'
22

33
import { ConfigInterface } from './types'
44

5-
const SWRConfigContext = createContext<ConfigInterface>({})
5+
const SWRConfigContext = createContext<Partial<ConfigInterface>>({})
66
SWRConfigContext.displayName = 'SWRConfigContext'
77

88
export default SWRConfigContext

src/types.ts

Lines changed: 21 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,50 +1,48 @@
1-
// `null` is used for a hack to manage shared state with SWR
2-
// https://github.com/vercel/swr/pull/918
3-
export type fetcherFn<Data> = ((...args: any) => Data | Promise<Data>) | null
1+
export type fetcherFn<Data> = (...args: any) => Data | Promise<Data>
42
export interface ConfigInterface<
53
Data = any,
64
Error = any,
75
Fn extends fetcherFn<Data> = fetcherFn<Data>
86
> {
9-
errorRetryInterval?: number
7+
errorRetryInterval: number
108
errorRetryCount?: number
11-
loadingTimeout?: number
12-
focusThrottleInterval?: number
13-
dedupingInterval?: number
14-
refreshInterval?: number
15-
refreshWhenHidden?: boolean
16-
refreshWhenOffline?: boolean
17-
revalidateOnFocus?: boolean
9+
loadingTimeout: number
10+
focusThrottleInterval: number
11+
dedupingInterval: number
12+
refreshInterval: number
13+
refreshWhenHidden: boolean
14+
refreshWhenOffline: boolean
15+
revalidateOnFocus: boolean
1816
revalidateOnMount?: boolean
19-
revalidateOnReconnect?: boolean
20-
shouldRetryOnError?: boolean
21-
fetcher?: Fn
22-
suspense?: boolean
17+
revalidateOnReconnect: boolean
18+
shouldRetryOnError: boolean
19+
fetcher: Fn
20+
suspense: boolean
2321
initialData?: Data
2422

25-
isOnline?: () => boolean
26-
isDocumentVisible?: () => boolean
27-
isPaused?: () => boolean
28-
onLoadingSlow?: (key: string, config: ConfigInterface<Data, Error>) => void
29-
onSuccess?: (
23+
isOnline: () => boolean
24+
isDocumentVisible: () => boolean
25+
isPaused: () => boolean
26+
onLoadingSlow: (key: string, config: ConfigInterface<Data, Error>) => void
27+
onSuccess: (
3028
data: Data,
3129
key: string,
3230
config: ConfigInterface<Data, Error>
3331
) => void
34-
onError?: (
32+
onError: (
3533
err: Error,
3634
key: string,
3735
config: ConfigInterface<Data, Error>
3836
) => void
39-
onErrorRetry?: (
37+
onErrorRetry: (
4038
err: Error,
4139
key: string,
4240
config: ConfigInterface<Data, Error>,
4341
revalidate: revalidateType,
4442
revalidateOpts: RevalidateOptionInterface
4543
) => void
4644

47-
compare?: (a: Data | undefined, b: Data | undefined) => boolean
45+
compare: (a: Data | undefined, b: Data | undefined) => boolean
4846
}
4947

5048
export interface RevalidateOptionInterface {

src/use-swr-infinite.ts

Lines changed: 16 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -34,39 +34,36 @@ function useSWRInfinite<Data = any, Error = any>(
3434
): SWRInfiniteResponseInterface<Data, Error>
3535
function useSWRInfinite<Data = any, Error = any>(
3636
getKey: KeyLoader<Data>,
37-
config?: SWRInfiniteConfigInterface<Data, Error>
37+
config?: Partial<SWRInfiniteConfigInterface<Data, Error>>
3838
): SWRInfiniteResponseInterface<Data, Error>
3939
function useSWRInfinite<Data = any, Error = any>(
4040
getKey: KeyLoader<Data>,
4141
fn?: fetcherFn<Data>,
42-
config?: SWRInfiniteConfigInterface<Data, Error>
42+
config?: Partial<SWRInfiniteConfigInterface<Data, Error>>
4343
): SWRInfiniteResponseInterface<Data, Error>
4444
function useSWRInfinite<Data = any, Error = any>(
45-
...args
45+
getKey: KeyLoader<Data>,
46+
...options: any[]
4647
): SWRInfiniteResponseInterface<Data, Error> {
47-
let getKey: KeyLoader<Data>,
48-
fn: fetcherFn<Data> | undefined,
49-
config: SWRInfiniteConfigInterface<Data, Error> = {}
48+
let _fn: fetcherFn<Data> | undefined,
49+
_config: Partial<SWRInfiniteConfigInterface<Data, Error>> = {}
5050

51-
if (args.length >= 1) {
52-
getKey = args[0]
53-
}
54-
if (args.length > 2) {
55-
fn = args[1]
56-
config = args[2]
51+
if (options.length > 1) {
52+
_fn = options[0]
53+
_config = options[1]
5754
} else {
58-
if (typeof args[1] === 'function') {
59-
fn = args[1]
60-
} else if (typeof args[1] === 'object') {
61-
config = args[1]
55+
if (typeof options[0] === 'function') {
56+
_fn = options[0]
57+
} else if (typeof options[0] === 'object') {
58+
_config = options[0]
6259
}
6360
}
6461

65-
config = Object.assign(
62+
const config: SWRInfiniteConfigInterface<Data, Error> = Object.assign(
6663
{},
6764
defaultConfig,
6865
useContext(SWRConfigContext),
69-
config
66+
_config
7067
)
7168
let {
7269
initialSize = 1,
@@ -76,11 +73,7 @@ function useSWRInfinite<Data = any, Error = any>(
7673
...extraConfig
7774
} = config
7875

79-
if (typeof fn === 'undefined') {
80-
// use the global fetcher
81-
// we have to convert the type here
82-
fn = (defaultFetcher as unknown) as fetcherFn<Data>
83-
}
76+
const fn = typeof _fn !== 'undefined' ? _fn : defaultFetcher
8477

8578
// get the serialized key of the first page
8679
let firstPageKey: string | null = null

src/use-swr.ts

Lines changed: 19 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -231,30 +231,29 @@ function useSWR<Data = any, Error = any>(
231231
): responseInterface<Data, Error>
232232
function useSWR<Data = any, Error = any>(
233233
key: keyInterface,
234-
config?: ConfigInterface<Data, Error>
234+
config?: Partial<ConfigInterface<Data, Error>>
235235
): responseInterface<Data, Error>
236236
function useSWR<Data = any, Error = any>(
237237
key: keyInterface,
238-
fn?: fetcherFn<Data>,
239-
config?: ConfigInterface<Data, Error>
238+
// `null` is used for a hack to manage shared state with SWR
239+
// https://github.com/vercel/swr/pull/918
240+
fn?: fetcherFn<Data> | null,
241+
config?: Partial<ConfigInterface<Data, Error>>
240242
): responseInterface<Data, Error>
241243
function useSWR<Data = any, Error = any>(
242-
...args
244+
_key: keyInterface,
245+
...options: any[]
243246
): responseInterface<Data, Error> {
244-
let _key: keyInterface,
245-
fn: fetcherFn<Data> | undefined,
246-
config: ConfigInterface<Data, Error> = {}
247-
if (args.length >= 1) {
248-
_key = args[0]
249-
}
250-
if (args.length > 2) {
251-
fn = args[1]
252-
config = args[2]
247+
let _fn: fetcherFn<Data> | undefined,
248+
_config: Partial<ConfigInterface<Data, Error>> = {}
249+
if (options.length > 1) {
250+
_fn = options[0]
251+
_config = options[1]
253252
} else {
254-
if (typeof args[1] === 'function') {
255-
fn = args[1]
256-
} else if (typeof args[1] === 'object') {
257-
config = args[1]
253+
if (typeof options[0] === 'function') {
254+
_fn = options[0]
255+
} else if (typeof options[0] === 'object') {
256+
_config = options[0]
258257
}
259258
}
260259

@@ -264,22 +263,19 @@ function useSWR<Data = any, Error = any>(
264263
// `keyErr` is the cache key for error objects
265264
const [key, fnArgs, keyErr, keyValidating] = cache.serializeKey(_key)
266265

267-
config = Object.assign(
266+
const config: ConfigInterface<Data, Error> = Object.assign(
268267
{},
269268
defaultConfig,
270269
useContext(SWRConfigContext),
271-
config
270+
_config
272271
)
273272

274273
const configRef = useRef(config)
275274
useIsomorphicLayoutEffect(() => {
276275
configRef.current = config
277276
})
278277

279-
if (typeof fn === 'undefined') {
280-
// use the global fetcher
281-
fn = config.fetcher
282-
}
278+
const fn = typeof _fn !== 'undefined' ? _fn : config.fetcher
283279

284280
const resolveData = () => {
285281
const cachedData = cache.get(key)

0 commit comments

Comments
 (0)