Skip to content

Commit 7ff0020

Browse files
committed
apply review change and type useSWRInfinite
1 parent 4a3a569 commit 7ff0020

File tree

7 files changed

+166
-45
lines changed

7 files changed

+166
-45
lines changed

immutable/index.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import useSWR, { Middleware, SWRHook } from 'swr'
1+
import useSWR, { Middleware } from 'swr'
22
import { withMiddleware } from '../src/utils/with-middleware'
33

44
export const immutable: Middleware = useSWRNext => (key, fetcher, config) => {
@@ -9,4 +9,4 @@ export const immutable: Middleware = useSWRNext => (key, fetcher, config) => {
99
return useSWRNext(key, fetcher, config)
1010
}
1111

12-
export default withMiddleware(useSWR as SWRHook, immutable)
12+
export default withMiddleware(useSWR, immutable)

infinite/index.ts

Lines changed: 43 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,9 @@ import useSWR, {
88
Fetcher,
99
SWRHook,
1010
MutatorCallback,
11-
Middleware
11+
Middleware,
12+
ValueKey,
13+
Result
1214
} from 'swr'
1315
import { useIsomorphicLayoutEffect } from '../src/utils/env'
1416
import { serialize } from '../src/utils/serialize'
@@ -18,18 +20,20 @@ import { SWRInfiniteConfiguration, SWRInfiniteResponse } from './types'
1820

1921
const INFINITE_PREFIX = '$inf$'
2022

21-
const getFirstPageKey = (getKey: KeyLoader<any>) => {
23+
const getFirstPageKey = (getKey: KeyLoader) => {
2224
return serialize(getKey ? getKey(0, null) : null)[0]
2325
}
2426

25-
export const unstable_serialize = (getKey: KeyLoader<any>) => {
27+
export const unstable_serialize = (getKey: KeyLoader) => {
2628
return INFINITE_PREFIX + getFirstPageKey(getKey)
2729
}
2830

29-
export const infinite = ((<Data, Error>(useSWRNext: SWRHook) => (
30-
getKey: KeyLoader<Data>,
31+
export const infinite = ((<Data, Error, Args extends ValueKey>(
32+
useSWRNext: SWRHook
33+
) => (
34+
getKey: KeyLoader<Args>,
3135
fn: Fetcher<Data> | null,
32-
config: typeof SWRConfig.default & SWRInfiniteConfiguration<Data, Error>
36+
config: typeof SWRConfig.default & SWRInfiniteConfiguration<Data, Error, Args>
3337
): SWRInfiniteResponse<Data, Error> => {
3438
const rerender = useState({})[1]
3539
const didMountRef = useRef<boolean>(false)
@@ -246,20 +250,39 @@ export const infinite = ((<Data, Error>(useSWRNext: SWRHook) => (
246250
} as SWRInfiniteResponse<Data, Error>
247251
}) as unknown) as Middleware
248252

249-
type SWRInfiniteHook = <Data = any, Error = any>(
250-
...args:
251-
| readonly [KeyLoader<Data>]
252-
| readonly [KeyLoader<Data>, Fetcher<Data> | null]
253-
| readonly [
254-
KeyLoader<Data>,
255-
SWRInfiniteConfiguration<Data, Error> | undefined
256-
]
257-
| readonly [
258-
KeyLoader<Data>,
259-
Fetcher<Data> | null,
260-
SWRInfiniteConfiguration<Data, Error> | undefined
261-
]
262-
) => SWRInfiniteResponse<Data, Error>
253+
export type InfiniteFetcher<
254+
Args extends ValueKey = ValueKey,
255+
Data = unknown
256+
> = Args extends (readonly [...infer K])
257+
? ((...args: [...K]) => Result<Data>)
258+
: Args extends (string | null)
259+
? Args extends (Record<any, any> | null)
260+
? never
261+
: (...args: [string]) => Result<Data>
262+
: Args extends (infer T)
263+
? (...args: [T]) => Result<Data>
264+
: never
265+
266+
interface SWRInfiniteHook {
267+
<Data = any, Error = any, Args extends ValueKey = ValueKey>(
268+
getKey: KeyLoader<Args>
269+
): SWRInfiniteResponse<Data, Error>
270+
<Data = any, Error = any, Args extends ValueKey = ValueKey>(
271+
getKey: KeyLoader<Args>,
272+
fn: InfiniteFetcher<Args, Data> | null
273+
): SWRInfiniteResponse<Data, Error>
274+
<Data = any, Error = any, Args extends ValueKey = ValueKey>(
275+
getKey: KeyLoader<Args>,
276+
config: SWRInfiniteConfiguration<Data, Error, Args> | undefined
277+
): SWRInfiniteResponse<Data, Error>
278+
<Data = any, Error = any, Args extends ValueKey = ValueKey>(
279+
...args: [
280+
KeyLoader<Args>,
281+
InfiniteFetcher<Args, Data> | null,
282+
SWRInfiniteConfiguration<Data, Error, Args> | undefined
283+
]
284+
): SWRInfiniteResponse<Data, Error>
285+
}
263286

264287
export default withMiddleware(useSWR, infinite) as SWRInfiniteHook
265288
export { SWRInfiniteConfiguration, SWRInfiniteResponse }

infinite/types.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
1-
import { SWRConfiguration, Fetcher, SWRResponse } from 'swr'
1+
import { SWRConfiguration, Fetcher, SWRResponse, ValueKey } from 'swr'
22

33
export type SWRInfiniteConfiguration<
44
Data = any,
5-
Error = any
6-
> = SWRConfiguration<Data[], Error, Fetcher<Data[]>> & {
5+
Error = any,
6+
Args extends ValueKey = ValueKey
7+
> = SWRConfiguration<Data[], Error, Args, Fetcher<Data[], Args>> & {
78
initialSize?: number
89
revalidateAll?: boolean
910
persistSize?: boolean

package.json

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -46,11 +46,7 @@
4646
"build:immutable": "bunchee index.ts --cwd immutable -m --no-sourcemap",
4747
"prepublishOnly": "yarn clean && yarn build",
4848
"publish-beta": "yarn publish --tag beta",
49-
"types:check": "yarn types:check:core && yarn types:check:infinite && yarn types:check:immutable && yarn types:check:fetcher",
50-
"types:check:core": "tsc --noEmit",
51-
"types:check:infinite": "cd infinite && tsc --noEmit",
52-
"types:check:immutable": "cd immutable && tsc --noEmit",
53-
"types:check:fetcher": "cd test-type && tsc --noEmit",
49+
"types:check": "tsc --noEmit",
5450
"format": "prettier --write ./**/*.{ts,tsx}",
5551
"lint": "eslint . --ext .ts,.tsx",
5652
"lint:fix": "yarn lint --fix",

src/types.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -143,9 +143,9 @@ export interface SWRHook {
143143
}
144144

145145
// Middlewares guarantee that a SWRHook receives a key, fetcher, and config as the argument
146-
type SWRHookWithMiddleware = <Data = any, Error = any>(
147-
key: Key,
148-
fetcher: Fetcher<Data, Key> | null,
146+
type SWRHookWithMiddleware = <Data = any, Error = any, Args extends Key = Key>(
147+
key: Args,
148+
fetcher: Fetcher<Data, Args> | null,
149149
config: SWRConfiguration<Data, Error>
150150
) => SWRResponse<Data, Error>
151151

@@ -216,8 +216,8 @@ export interface SWRResponse<Data, Error> {
216216
isValidating: boolean
217217
}
218218

219-
export type KeyLoader<Data = any> =
220-
| ((index: number, previousPageData: Data | null) => ValueKey)
219+
export type KeyLoader<Args extends ValueKey = ValueKey> =
220+
| ((index: number, previousPageData: any | null) => Args)
221221
| null
222222

223223
export interface RevalidatorOptions {

test-type/fetcher.ts

Lines changed: 109 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,17 @@
11
import useSWR from 'swr'
2+
import useSWRInfinite from 'swr/infinite'
3+
24
type ExpectType = <T>(value: T) => void
35
const expectType: ExpectType = () => {}
46

5-
const cond: () => boolean = () => true
7+
const truthy: () => boolean = () => true
68

79
export function useString() {
810
useSWR('/api/user', key => {
911
expectType<string>(key)
1012
return key
1113
})
12-
useSWR(cond() ? '/api/user' : null, key => {
14+
useSWR(truthy() ? '/api/user' : null, key => {
1315
expectType<string>(key)
1416
return key
1517
})
@@ -20,7 +22,7 @@ export function useRecord() {
2022
expectType<{ a: string; b: { c: string; d: number } }>(key)
2123
return key
2224
})
23-
useSWR(cond() ? { a: '1', b: { c: '3', d: 2 } } : null, key => {
25+
useSWR(truthy() ? { a: '1', b: { c: '3', d: 2 } } : null, key => {
2426
expectType<{ a: string; b: { c: string; d: number } }>(key)
2527
return key
2628
})
@@ -32,7 +34,7 @@ export function useTuple() {
3234
return keys
3335
})
3436
useSWR(
35-
cond() ? [{ a: '1', b: { c: '3' } }, [1231, '888']] : null,
37+
truthy() ? [{ a: '1', b: { c: '3' } }, [1231, '888']] : null,
3638
(...keys) => {
3739
expectType<[{ a: string; b: { c: string } }, (string | number)[]]>(keys)
3840
return keys
@@ -56,7 +58,7 @@ export function useReadonlyTuple() {
5658
return keys
5759
})
5860
useSWR(
59-
cond() ? ([{ a: '1', b: { c: '3' } }, [1231, '888']] as const) : null,
61+
truthy() ? ([{ a: '1', b: { c: '3' } }, [1231, '888']] as const) : null,
6062
(...keys) => {
6163
expectType<
6264
[
@@ -83,7 +85,27 @@ export function useReturnString() {
8385
}
8486
)
8587
useSWR(
86-
() => (cond() ? '/api/user' : null),
88+
() => (truthy() ? '/api/user' : null),
89+
key => {
90+
expectType<string>(key)
91+
return key
92+
}
93+
)
94+
95+
useSWRInfinite(
96+
(index, previousPageData: string) => {
97+
return `${index}${previousPageData}`
98+
},
99+
key => {
100+
expectType<string>(key)
101+
return key
102+
}
103+
)
104+
105+
useSWRInfinite(
106+
(index, previousPageData: string) => {
107+
return truthy() ? `${index}${previousPageData}` : null
108+
},
87109
key => {
88110
expectType<string>(key)
89111
return key
@@ -100,12 +122,37 @@ export function useReturnRecord() {
100122
}
101123
)
102124
useSWR(
103-
() => (cond() ? { a: '1', b: { c: '3', d: 2 } } : null),
125+
() => (truthy() ? { a: '1', b: { c: '3', d: 2 } } : null),
104126
key => {
105127
expectType<{ a: string; b: { c: string; d: number } }>(key)
106128
return key
107129
}
108130
)
131+
132+
useSWRInfinite(
133+
index => ({
134+
index,
135+
endPoint: '/api'
136+
}),
137+
key => {
138+
expectType<{ index: number; endPoint: string }>(key)
139+
return [key]
140+
}
141+
)
142+
143+
useSWRInfinite(
144+
index =>
145+
truthy()
146+
? {
147+
index,
148+
endPoint: '/api'
149+
}
150+
: null,
151+
key => {
152+
expectType<{ index: number; endPoint: string }>(key)
153+
return [key]
154+
}
155+
)
109156
}
110157

111158
export function useReturnTuple() {
@@ -117,12 +164,29 @@ export function useReturnTuple() {
117164
}
118165
)
119166
useSWR(
120-
() => (cond() ? [{ a: '1', b: { c: '3' } }, [1231, '888']] : null),
167+
() => (truthy() ? [{ a: '1', b: { c: '3' } }, [1231, '888']] : null),
121168
(...keys) => {
122169
expectType<[{ a: string; b: { c: string } }, (string | number)[]]>(keys)
123170
return keys
124171
}
125172
)
173+
174+
useSWRInfinite(
175+
index => [{ a: '1', b: { c: '3', d: index } }, [1231, '888']],
176+
(...keys) => {
177+
expectType<[{ a: string; b: { c: string } }, (string | number)[]]>(keys)
178+
return keys[1]
179+
}
180+
)
181+
182+
useSWRInfinite(
183+
index =>
184+
truthy() ? [{ a: '1', b: { c: '3', d: index } }, [1231, '888']] : null,
185+
(...keys) => {
186+
expectType<[{ a: string; b: { c: string } }, (string | number)[]]>(keys)
187+
return keys[1]
188+
}
189+
)
126190
}
127191

128192
export function useReturnReadonlyTuple() {
@@ -145,7 +209,7 @@ export function useReturnReadonlyTuple() {
145209
)
146210
useSWR(
147211
() =>
148-
cond() ? ([{ a: '1', b: { c: '3' } }, [1231, '888']] as const) : null,
212+
truthy() ? ([{ a: '1', b: { c: '3' } }, [1231, '888']] as const) : null,
149213
(...keys) => {
150214
expectType<
151215
[
@@ -161,4 +225,40 @@ export function useReturnReadonlyTuple() {
161225
return keys
162226
}
163227
)
228+
229+
useSWRInfinite(
230+
() => [{ a: '1', b: { c: '3' } }, [1231, '888']] as const,
231+
(...keys) => {
232+
expectType<
233+
[
234+
{
235+
readonly a: '1'
236+
readonly b: {
237+
readonly c: '3'
238+
}
239+
},
240+
readonly [1231, '888']
241+
]
242+
>(keys)
243+
return keys
244+
}
245+
)
246+
useSWRInfinite(
247+
() =>
248+
truthy() ? ([{ a: '1', b: { c: '3' } }, [1231, '888']] as const) : null,
249+
(...keys) => {
250+
expectType<
251+
[
252+
{
253+
readonly a: '1'
254+
readonly b: {
255+
readonly c: '3'
256+
}
257+
},
258+
readonly [1231, '888']
259+
]
260+
>(keys)
261+
return keys[1]
262+
}
263+
)
164264
}

tsconfig.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,8 @@
2727
"include": [
2828
"src",
2929
"immutable",
30-
"infinite"
30+
"infinite",
31+
"test-type"
3132
],
3233
"exclude": [
3334
"./**/dist",

0 commit comments

Comments
 (0)