Skip to content

Commit 8a8b362

Browse files
committed
chore: More work on interface changes
1 parent e2dd554 commit 8a8b362

File tree

2 files changed

+154
-79
lines changed

2 files changed

+154
-79
lines changed

src/createLoader.ts

Lines changed: 68 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,34 @@
11
import { aggregateToQuery } from "./aggregateToQuery";
2+
import { useCreateQuery } from "./createQuery";
23
import { RTKLoader } from "./RTKLoader";
34
import * as Types from "./types";
45

56
export const createUseLoader = <
6-
QRU extends readonly Types.UseQueryResult<unknown>[],
7-
QRUD extends readonly Types.UseQueryResult<unknown>[],
8-
R extends unknown = Types.MakeDataRequired<QRU>,
7+
Q extends Types._Q,
8+
D extends Types._D,
9+
E extends Types._E,
10+
R extends unknown = Types.DataShape<
11+
Types.MakeDataRequired<Q>,
12+
D,
13+
E
14+
>,
915
A = never
1016
>(
11-
createUseLoaderArgs: Types.CreateUseLoaderArgs<QRU, QRUD, R, A>
17+
createUseLoaderArgs: Types.CreateUseLoaderArgs<Q, D, E, R, A>
1218
): Types.UseLoader<A, R> => {
1319
const useLoader = (...args: Types.OptionalGenericArg<A>) => {
14-
const createdQueries = createUseLoaderArgs.queries(...args);
15-
const deferredQueries =
16-
createUseLoaderArgs.deferredQueries?.(...args) ?? [];
17-
const aggregatedQuery = aggregateToQuery(createdQueries);
20+
const loaderRes = createUseLoaderArgs.useQuery(...args);
21+
const queriesList = loaderRes.queries
22+
? Object.keys(loaderRes.queries).map(
23+
(key) => (loaderRes.queries as Q)[key]
24+
)
25+
: [];
26+
const aggregatedQuery = aggregateToQuery(queriesList);
1827

19-
if (
20-
aggregatedQuery.isSuccess ||
21-
createdQueries.length === 0
22-
) {
28+
if (aggregatedQuery.isSuccess || queriesList.length === 0) {
2329
const data = createUseLoaderArgs.transform
24-
? createUseLoaderArgs.transform(
25-
createdQueries as unknown as Types.MakeDataRequired<QRU>,
26-
deferredQueries as QRUD
27-
)
28-
: createdQueries;
30+
? createUseLoaderArgs.transform(loaderRes)
31+
: loaderRes;
2932

3033
return {
3134
...aggregatedQuery,
@@ -43,21 +46,25 @@ export const createUseLoader = <
4346

4447
export const createLoader = <
4548
P extends unknown,
46-
QRU extends readonly Types.UseQueryResult<unknown>[] = [],
47-
QRUD extends readonly Types.UseQueryResult<unknown>[] = [],
48-
R extends unknown = Types.MakeDataRequired<QRU>,
49-
A = never
49+
Q extends Types._Q = Types._Q,
50+
D extends Types._D = Types._D,
51+
E extends Types._E = Types._E,
52+
R extends unknown = Types.DataShape<
53+
Types.MakeDataRequired<Q>,
54+
D,
55+
E
56+
>,
57+
A extends unknown = never
5058
>(
51-
createLoaderArgs: Types.CreateLoaderArgs<P, QRU, QRUD, R, A>
52-
): Types.Loader<P, R, QRU, A> => {
59+
createLoaderArgs: Types.CreateLoaderArgs<P, Q, D, E, R, A>
60+
): Types.Loader<P, R, Q, D, E, A> => {
5361
const useLoader = createUseLoader({
54-
queries:
55-
createLoaderArgs.queries ?? (() => [] as unknown as QRU),
62+
useQuery:
63+
createLoaderArgs.useQuery ?? (() => ({} as unknown as Q)),
5664
transform: createLoaderArgs.transform,
57-
deferredQueries: createLoaderArgs.deferredQueries,
5865
});
5966

60-
const loader: Types.Loader<P, R, QRU, A> = {
67+
const loader: Types.Loader<P, R, Q, D, E, A> = {
6168
useLoader,
6269
onLoading: createLoaderArgs.onLoading,
6370
onError: createLoaderArgs.onError,
@@ -67,31 +74,35 @@ export const createLoader = <
6774
LoaderComponent:
6875
createLoaderArgs.loaderComponent ?? RTKLoader,
6976
extend: function <
70-
QRUb extends readonly Types.UseQueryResult<unknown>[],
71-
QRUDb extends readonly Types.UseQueryResult<unknown>[],
77+
Qb extends Types._Q,
78+
Db extends Types._D = Types._D,
79+
Eb extends Types._E = Types._E,
7280
Pb extends unknown = P,
73-
Rb = QRUb extends unknown
81+
Rb = Qb extends unknown
7482
? R
75-
: Types.MakeDataRequired<QRUb>,
83+
: Types.DataShape<Types.MakeDataRequired<Qb>, Db, Eb>,
7684
Ab = A
7785
>({
78-
queries,
79-
deferredQueries,
86+
useQuery,
8087
transform,
8188
...loaderArgs
82-
}: Partial<
83-
Types.CreateLoaderArgs<Pb, QRUb, QRUDb, Rb, Ab>
84-
>) {
89+
}: Partial<Types.CreateLoaderArgs<Pb, Qb, Db, Eb, Rb, Ab>>) {
8590
const extendedLoader = {
86-
...(this as unknown as Types.Loader<Pb, Rb, QRUb, Ab>),
91+
...(this as unknown as Types.Loader<
92+
Pb,
93+
Rb,
94+
Qb,
95+
Db,
96+
Eb,
97+
Ab
98+
>),
8799
...loaderArgs,
88-
} as Types.Loader<Pb, Rb, QRUb, Ab>;
100+
} as Types.Loader<Pb, Rb, Qb, Db, Eb, Ab>;
89101

90-
if (queries) {
102+
if (useQuery) {
91103
const newUseLoader = createUseLoader({
92-
queries,
104+
useQuery,
93105
transform,
94-
deferredQueries,
95106
});
96107
extendedLoader.useLoader = newUseLoader;
97108
}
@@ -102,3 +113,19 @@ export const createLoader = <
102113

103114
return loader;
104115
};
116+
117+
const loader = createLoader({
118+
queriesArg: (props: {}) => "test",
119+
useQuery: (arg) => {
120+
const q1 = useCreateQuery(async () => "foo" as const);
121+
const q2 = useCreateQuery(async () => "bar" as const);
122+
return {
123+
queries: {
124+
q1,
125+
},
126+
deferredQueries: {
127+
q2,
128+
},
129+
};
130+
},
131+
});

src/types.ts

Lines changed: 86 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { SerializedError } from "@reduxjs/toolkit";
22
import { FetchBaseQueryError } from "@reduxjs/toolkit/dist/query";
33
import { ReactElement } from "react";
4+
import { useCreateQuery } from "./createQuery";
45

56
/** Result of a RTK useQuery hook */
67
export type UseQueryResult<T> = {
@@ -38,52 +39,62 @@ export type UseQueryResult<T> = {
3839
refetch: () => void;
3940
};
4041

41-
export type MakeDataRequired<
42-
T extends readonly UseQueryResult<unknown>[]
43-
> = {
42+
/** _X are types that are extended from in the generics */
43+
export type _Q = Record<string, UseQueryResult<unknown>>;
44+
export type _D = Record<string, UseQueryResult<unknown>>;
45+
export type _E = unknown;
46+
export type _P = Record<string, unknown>;
47+
export type _R = unknown;
48+
49+
export type MakeDataRequired<T extends _Q> = {
4450
// @ts-ignore: TS2536: Type '"data"' cannot be used to index type 'T[K]'.
4551
[K in keyof T]: T[K] & { data: NonNullable<T[K]["data"]> };
4652
};
4753

54+
export type DataShape<
55+
Q extends _Q,
56+
D extends _D,
57+
E extends _E
58+
> = {
59+
queries?: Q;
60+
deferredQueries?: D;
61+
payload?: E;
62+
};
63+
4864
/** Use: `(...args: OptionalGenericArg<T>) => void;`
4965
* Allows either `T` or `none` for the parameter
5066
*/
5167
export type OptionalGenericArg<T> = T extends never ? [] : [T];
5268

5369
export type LoaderTransformFunction<
54-
QRU extends readonly UseQueryResult<unknown>[],
55-
QRUD extends readonly UseQueryResult<unknown>[],
70+
Q extends _Q,
71+
D extends _D,
72+
E extends _E,
5673
R extends unknown
57-
> = (queries: MakeDataRequired<QRU>, deferredQueries: QRUD) => R;
74+
> = (data: DataShape<MakeDataRequired<Q>, D, E>) => R;
5875

5976
export type CreateUseLoaderArgs<
60-
QRU extends readonly UseQueryResult<unknown>[],
61-
QRUD extends readonly UseQueryResult<unknown>[],
62-
R extends unknown,
77+
Q extends _Q,
78+
D extends _D,
79+
E extends _E,
80+
R extends _R,
6381
A = never
6482
> = {
6583
/** Should return a list of RTK useQuery results.
6684
* Example:
6785
* ```typescript
68-
* (args: Args) => [
69-
* useGetPokemonQuery(args.pokemonId),
70-
* useGetSomethingElse(args.someArg)
71-
* ] as const
86+
* (args: Args) => ({
87+
* queries: {
88+
* pokemon: useGetPokemonQuery(args.pokemonId),
89+
* }
90+
* })
7291
* ```
7392
*/
74-
queries: (...args: OptionalGenericArg<A>) => QRU;
75-
/** Should return a list of RTK useQuery results.
76-
* Example:
77-
* ```typescript
78-
* (args: Args) => [
79-
* useGetPokemonQuery(args.pokemonId),
80-
* useGetSomethingElse(args.someArg)
81-
* ] as const
82-
* ```
83-
*/
84-
deferredQueries?: (...args: OptionalGenericArg<A>) => QRUD;
93+
useQuery: (
94+
...args: OptionalGenericArg<A>
95+
) => DataShape<Q, D, E>;
8596
/** Transforms the output of the queries */
86-
transform?: LoaderTransformFunction<QRU, QRUD, R>;
97+
transform?: (data: DataShape<Q, D, E>) => R;
8798
};
8899

89100
export type UseLoader<A, R> = (
@@ -147,11 +158,12 @@ export type CustomLoaderProps<T = unknown> = {
147158

148159
export type CreateLoaderArgs<
149160
P extends unknown,
150-
QRU extends readonly UseQueryResult<unknown>[],
151-
QRUD extends readonly UseQueryResult<unknown>[],
152-
R extends unknown = MakeDataRequired<QRU>,
161+
Q extends _Q,
162+
D extends _D,
163+
E extends _E,
164+
R extends unknown = MakeDataRequired<Q>,
153165
A = never
154-
> = Partial<CreateUseLoaderArgs<QRU, QRUD, R, A>> & {
166+
> = Partial<CreateUseLoaderArgs<Q, D, E, R, A>> & {
155167
/** Generates an argument for the `queries` based on component props */
156168
queriesArg?: (props: P) => A;
157169
/** Determines what to render while loading (with no data to fallback on) */
@@ -176,7 +188,9 @@ export type CreateLoaderArgs<
176188
export type Loader<
177189
P extends unknown,
178190
R extends unknown,
179-
QRU extends readonly UseQueryResult<unknown>[] = [],
191+
Q extends _Q = _Q,
192+
D extends _D = _D,
193+
E extends _E = _E,
180194
A = never
181195
> = {
182196
/** A hook that runs all queries and returns aggregated result */
@@ -200,18 +214,26 @@ export type Loader<
200214
whileFetching?: WhileFetchingArgs<P, R>;
201215
/** Returns a new `Loader` extended from this `Loader`, with given overrides. */
202216
extend: <
203-
QRUb extends readonly UseQueryResult<unknown>[] = QRU,
204-
QRUDb extends readonly UseQueryResult<unknown>[] = [],
217+
Qb extends _Q = Q,
218+
Db extends _D = _Q,
219+
Eb extends _E = _E,
205220
Pb extends unknown = P,
206-
Rb extends unknown = QRUb extends QRU
221+
Rb extends unknown = Qb extends Q
207222
? R extends never
208-
? QRU
223+
? Q
209224
: R
210-
: MakeDataRequired<QRUb>,
225+
: DataShape<MakeDataRequired<Qb>, Db, Eb>,
211226
Ab = A
212227
>(
213-
newLoader: Partial<CreateLoaderArgs<Pb, QRUb, QRUDb, Rb, Ab>>
214-
) => Loader<Pb, Rb, QRUb extends never ? QRU : QRUb, Ab>;
228+
newLoader: Partial<CreateLoaderArgs<Pb, Qb, Db, Rb, Ab>>
229+
) => Loader<
230+
Pb,
231+
Rb,
232+
Qb extends never ? Q : Qb,
233+
Qb extends never ? D : Db,
234+
Qb extends never ? E : Eb,
235+
Ab
236+
>;
215237
/** The component to use to switch between rendering the different query states. */
216238
LoaderComponent: Component<CustomLoaderProps>;
217239
};
@@ -246,4 +268,30 @@ export type WithLoaderArgs<
246268
P extends unknown,
247269
R extends unknown,
248270
A = never
249-
> = Loader<P, R, [], A>;
271+
> = Loader<P, R, _Q, _Q, unknown, A>;
272+
273+
const _createLoaderTypeTest = <
274+
P extends unknown,
275+
Q extends _Q,
276+
D extends _D,
277+
E extends _E,
278+
R extends unknown = MakeDataRequired<Q>,
279+
A = never
280+
>(
281+
args: CreateLoaderArgs<P, Q, D, E, R>
282+
): Loader<P, R, Q, D, A> => {
283+
return {} as Loader<P, R, Q, D, A>;
284+
};
285+
286+
const asd = _createLoaderTypeTest({
287+
useQuery: () => {
288+
return {
289+
queries: {
290+
test: useCreateQuery(async () => "foo" as const),
291+
},
292+
deferredQueries: {
293+
best: useCreateQuery(async () => "bar" as const),
294+
},
295+
};
296+
},
297+
});

0 commit comments

Comments
 (0)