Skip to content

Commit 9b19dba

Browse files
committed
fix: extend types
1 parent 553762b commit 9b19dba

File tree

3 files changed

+62
-35
lines changed

3 files changed

+62
-35
lines changed

src/createLoader.ts

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -82,18 +82,21 @@ export const createLoader = <
8282
LoaderComponent:
8383
createLoaderArgs.loaderComponent ?? RTKLoader,
8484
extend: function <
85-
Qb extends Types._Q,
86-
Db extends Types._D,
87-
Eb extends Types._E,
88-
Pb extends unknown = P,
89-
Rb = Qb extends unknown
85+
Qb extends Types._Q = Q,
86+
Db extends Types._D = D,
87+
Eb extends Types._E = E,
88+
Rb extends unknown = Types.AllEql<
89+
Q,
90+
Qb,
91+
D,
92+
Db,
93+
E,
94+
Eb
95+
> extends true
9096
? R
91-
: Types.ResolveDataShape<
92-
Types.MakeDataRequired<Qb>,
93-
Db,
94-
Eb
95-
>,
96-
Ab extends unknown = A
97+
: Types.ResolveLoadedDataShape<Qb, Db, Eb>,
98+
Pb extends unknown = P,
99+
Ab = A
97100
>({
98101
useQueries,
99102
transform,

src/types.ts

Lines changed: 36 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,22 @@ import { SerializedError } from "@reduxjs/toolkit";
22
import { FetchBaseQueryError } from "@reduxjs/toolkit/dist/query";
33
import { ReactElement } from "react";
44

5+
export type AllNever<Q, D, E, R = never> =
6+
| Q
7+
| D
8+
| E
9+
| R extends never
10+
? true
11+
: false;
12+
13+
export type AllEql<Q, Qb, D, Db, E, Eb> = Q extends Qb
14+
? D extends Db
15+
? E extends Eb
16+
? true
17+
: false
18+
: false
19+
: false;
20+
521
/** Result of a RTK useQuery hook */
622
export type UseQueryResult<T> = {
723
// Base query state
@@ -39,9 +55,9 @@ export type UseQueryResult<T> = {
3955
};
4056

4157
/** _X are types that are extended from in the generics */
42-
export type _Q = Record<string, UseQueryResult<unknown>>;
43-
export type _D = Record<string, UseQueryResult<unknown>>;
44-
export type _E = unknown;
58+
export type _Q = Record<string, UseQueryResult<unknown>> | never;
59+
export type _D = Record<string, UseQueryResult<unknown>> | never;
60+
export type _E = unknown | never;
4561
export type _P = Record<string, unknown>;
4662
export type _R = unknown;
4763

@@ -50,7 +66,7 @@ export type MakeDataRequired<T extends _Q> = {
5066
[K in keyof T]: T[K] & { data: NonNullable<T[K]["data"]> };
5167
};
5268

53-
export type DataShape<
69+
export type DataShapeInput<
5470
Q extends _Q,
5571
D extends _D,
5672
E extends _E
@@ -82,6 +98,12 @@ export type ResolveDataShape<
8298
: { queries: Q; deferredQueries: D }
8399
: { queries: Q; deferredQueries: D; payload: E };
84100

101+
export type ResolveLoadedDataShape<
102+
Q extends _Q,
103+
D extends _D,
104+
E extends _E
105+
> = ResolveDataShape<MakeDataRequired<Q>, D, E>;
106+
85107
/** Use: `(...args: OptionalGenericArg<T>) => void;`
86108
* Allows either `T` or `none` for the parameter
87109
*/
@@ -92,7 +114,7 @@ export type LoaderTransformFunction<
92114
D extends _D,
93115
E extends _E,
94116
R extends unknown
95-
> = (data: ResolveDataShape<MakeDataRequired<Q>, D, E>) => R;
117+
> = (data: ResolveLoadedDataShape<Q, D, E>) => R;
96118

97119
export type CreateUseLoaderArgs<
98120
Q extends _Q,
@@ -113,11 +135,9 @@ export type CreateUseLoaderArgs<
113135
*/
114136
useQueries: (
115137
...args: OptionalGenericArg<A>
116-
) => DataShape<Q, D, E>;
138+
) => DataShapeInput<Q, D, E>;
117139
/** Transforms the output of the queries */
118-
transform?: (
119-
data: ResolveDataShape<MakeDataRequired<Q>, D, E>
120-
) => R;
140+
transform?: (data: ResolveLoadedDataShape<Q, D, E>) => R;
121141
};
122142

123143
export type UseLoader<A, R, Q extends _Q, D extends _D, E> = {
@@ -188,7 +208,7 @@ export type CreateLoaderArgs<
188208
Q extends _Q,
189209
D extends _D,
190210
E extends _E,
191-
R extends unknown = MakeDataRequired<Q>,
211+
R extends unknown,
192212
A = never
193213
> = Partial<CreateUseLoaderArgs<Q, D, E, R, A>> & {
194214
/** Generates an argument for the `queries` based on component props */
@@ -226,9 +246,9 @@ export type CreateLoader<
226246
export type Loader<
227247
P extends unknown,
228248
R extends unknown,
229-
Q extends _Q,
230-
D extends _D,
231-
E extends _E,
249+
Q extends _Q = never,
250+
D extends _D = never,
251+
E extends _E = never,
232252
A = never
233253
> = {
234254
/** A hook that runs all queries and returns aggregated result */
@@ -255,16 +275,10 @@ export type Loader<
255275
Qb extends _Q = Q,
256276
Db extends _D = D,
257277
Eb extends _E = E,
278+
Rb extends unknown = AllEql<Q, Qb, D, Db, E, Eb> extends true
279+
? R
280+
: ResolveLoadedDataShape<Qb, Db, Eb>,
258281
Pb extends unknown = P,
259-
Rb extends unknown = ResolveDataShape<
260-
Qb,
261-
Db,
262-
Eb
263-
> extends never
264-
? R extends never
265-
? Q
266-
: R
267-
: ResolveDataShape<MakeDataRequired<Qb>, Db, Eb>,
268282
Ab = A
269283
>(
270284
newLoader: Partial<CreateLoaderArgs<Pb, Qb, Db, Eb, Rb, Ab>>

testing-app/src/tests.test.tsx

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -549,6 +549,7 @@ describe("withLoader", () => {
549549
return (
550550
<div>
551551
<div>{loader.queries.pokemon.data.name}</div>
552+
<div>{loader.foobar}</div>
552553
<button
553554
onClick={() => loader.payload.setName("error")}
554555
>
@@ -575,18 +576,27 @@ describe("withLoader", () => {
575576
},
576577
})
577578
.extend({
578-
onLoading: () => <div>Extended Loading</div>,
579+
onLoading: () => <div>Extended Loading One</div>,
579580
})
580581
.extend({
581582
onError: () => <div>Extended Error</div>,
582583
})
584+
.extend({
585+
transform: (data) => ({ ...data, foobar: "foobar" }),
586+
})
587+
.extend({
588+
onLoading: () => <div>Extended Loading Two</div>,
589+
})
583590
);
584591

585592
render(<Component />);
586-
expect(screen.getByText("Extended Loading")).toBeVisible();
593+
expect(
594+
screen.getByText("Extended Loading Two")
595+
).toBeVisible();
587596
await waitFor(() =>
588597
expect(screen.getByText("charizard")).toBeVisible()
589598
);
599+
expect(screen.getByText("foobar")).toBeVisible();
590600
await userEvent.click(screen.getByRole("button"));
591601
await waitFor(() =>
592602
expect(screen.getByText("Extended Error")).toBeVisible()

0 commit comments

Comments
 (0)