Skip to content

Commit 7ed7459

Browse files
committed
chore: Better type resolving
1 parent 024b53d commit 7ed7459

File tree

4 files changed

+44
-20
lines changed

4 files changed

+44
-20
lines changed

README.md

Lines changed: 28 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -202,20 +202,36 @@ type LoaderData = InferLoaderData<typeof useLoader>;
202202

203203
Typescript should infer the loader data type automatically inside `withLoader`, but if you need the type elsewhere then this could be useful.
204204

205-
## Future features & wants
205+
# Extending loaders
206206

207-
- Better type resolving:
207+
You can extend a loader like such:
208+
209+
```tsx
210+
const baseLoader = createLoader({
211+
onLoading: () => <Loading />,
212+
});
213+
214+
const pokemonLoader = baseLoader.extend({
215+
queries: (name: string) => [useGetPokemon(name)],
216+
queriesArg: (props: PokemonProps) => props.name.toLowerCase(),
217+
});
218+
```
219+
220+
New properties will overwrite existing.
221+
222+
> If the loader you extend has a `transform` function, and you are changing the `queries` function, you might need to do this to resolve the types properly:
208223
209224
```typescript
210-
createLoader({
211-
queries: () => {
212-
return [useGetUser(), useGetPosts()] as const;
213-
},
214-
transform: function (queries) {
215-
// queries here are guaranteed to have .data, but currently the type resolves data as optional.
216-
return {
217-
name: queries[0].data.name, // is technically safe, but typescript might complain
218-
};
219-
},
225+
const baseLoader = createLoader({
226+
queries: () => [...],
227+
transform: () => {i_want: "this-format"},
228+
})
229+
230+
const pokemonLoader = baseLoader.extend({
231+
queries: () => [...],
232+
transform: (q) => q, // Reapply default transform for query
220233
});
234+
235+
type Test = ReturnType<typeof pokemonLoader.useLoader>;
236+
// { i_want: string; }
221237
```

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@ryfylke-react/rtk-query-loader",
3-
"version": "0.2.6",
3+
"version": "0.2.7",
44
"description": "Lets you create loaders that contain multiple RTK queries.",
55
"main": "./dist/cjs/index.js",
66
"module": "./dist/esm/index.js",

src/createLoader.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import * as Types from "./types";
33

44
export const createUseLoader = <
55
QRU extends readonly Types.UseQueryResult<unknown>[],
6-
R extends unknown = QRU,
6+
R extends unknown = Types.MakeDataRequired<QRU>,
77
A = never
88
>(
99
createUseLoaderArgs: Types.CreateUseLoaderArgs<QRU, R, A>
@@ -15,7 +15,9 @@ export const createUseLoader = <
1515

1616
if (aggregatedQuery.isSuccess) {
1717
const data = createUseLoaderArgs.transform
18-
? createUseLoaderArgs.transform(createdQueries)
18+
? createUseLoaderArgs.transform(
19+
createdQueries as unknown as Types.MakeDataRequired<QRU>
20+
)
1921
: createdQueries;
2022

2123
return {
@@ -32,7 +34,7 @@ export const createUseLoader = <
3234
export const createLoader = <
3335
P extends unknown,
3436
QRU extends readonly Types.UseQueryResult<unknown>[],
35-
R extends unknown = QRU,
37+
R extends unknown = Types.MakeDataRequired<QRU>,
3638
A = never
3739
>(
3840
createLoaderArgs: Types.CreateLoaderArgs<P, QRU, R, A>

src/types.ts

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,14 @@ export type UseQueryResult<T> = {
2323
refetch: () => void; // A function to force refetch the query
2424
};
2525

26+
export type MakeDataRequired<T> = {
27+
[K in keyof T]-?: Required<T[K]>;
28+
};
29+
2630
export type LoaderTransformFunction<
2731
QRU extends readonly UseQueryResult<unknown>[],
2832
R extends unknown
29-
> = (queries: QRU) => R;
33+
> = (queries: MakeDataRequired<QRU>) => R;
3034

3135
export type OptionalGenericArg<T> = T extends never ? [] : [T];
3236

@@ -45,7 +49,7 @@ export type UseLoader<A, R> = (
4549

4650
export type CreateLoaderType = <
4751
QRU extends readonly UseQueryResult<unknown>[],
48-
R extends unknown = QRU,
52+
R extends unknown = MakeDataRequired<QRU>,
4953
A = never
5054
>(
5155
createLoaderArgs: CreateUseLoaderArgs<QRU, R, A>
@@ -77,7 +81,7 @@ export type WithLoaderArgs<
7781
export type CreateLoaderArgs<
7882
P extends unknown,
7983
QRU extends readonly UseQueryResult<unknown>[],
80-
R extends unknown = QRU,
84+
R extends unknown = MakeDataRequired<QRU>,
8185
A = never
8286
> = Partial<CreateUseLoaderArgs<QRU, R, A>> & {
8387
queriesArg?: (props: P) => A;
@@ -108,7 +112,9 @@ export type Loader<
108112
extend: <
109113
QRUb extends readonly UseQueryResult<unknown>[],
110114
Pb extends unknown = P,
111-
Rb extends unknown = QRUb extends unknown ? R : QRUb,
115+
Rb extends unknown = QRUb extends unknown
116+
? R
117+
: MakeDataRequired<QRUb>,
112118
Ab = A
113119
>(
114120
newLoader: Partial<CreateLoaderArgs<Pb, QRUb, Rb, Ab>>

0 commit comments

Comments
 (0)