1
1
import type { AxiosResponse , AxiosRequestConfig , AxiosInstance } from "axios"
2
- import type { SetOptional , Except , Simplify } from "type-fest"
2
+ import type { SetOptional , Except , Simplify , Split } from "type-fest"
3
3
4
4
export type HTTPMethod =
5
5
| "GET"
@@ -29,6 +29,20 @@ export type APIDefToUnion<Routes extends APIDef> = Routes extends RouteDef[]
29
29
? Routes [ keyof Routes ]
30
30
: never
31
31
32
+ // Given a union of {method: "GET" | "POST", ...} | {method: "PATCH", ...} converts it to a union of
33
+ // {method: "GET", ...} | {method: "POST", ...} | {method: "PATCH", ...}
34
+ export type ExplodeMethodsOnRouteDef < Route extends RouteDef > = Route extends any
35
+ ? Route extends { method : infer Method }
36
+ ? Method extends HTTPMethod
37
+ ? Simplify <
38
+ {
39
+ method : Method
40
+ } & Except < Route , "method" >
41
+ >
42
+ : never
43
+ : never
44
+ : never
45
+
32
46
// Converts from `/things/[thing_id]/get` to `/things/${string}/get`
33
47
export type ReplacePathParams < Path extends string > =
34
48
Path extends `${infer Before } [${infer Param } ]${infer After } `
@@ -37,40 +51,31 @@ export type ReplacePathParams<Path extends string> =
37
51
38
52
// Converts from `/things/example_thing_id/get` to `/things/${string}/get`
39
53
export type WidenConcretePathParams <
40
- Path extends string ,
54
+ Path extends AnyRoutePath < Route > ,
41
55
Route extends RouteDef
42
- > = Path extends ReplacePathParams < Route [ "route" ] >
43
- ? ReplacePathParams < Route [ "route" ] >
56
+ > = Route extends any
57
+ ? Route extends { route : infer WidenedPath }
58
+ ? Path extends WidenedPath
59
+ ? WidenedPath
60
+ : never
61
+ : never
44
62
: never
45
63
46
- export type ReplacePathParamsOnRouteDef < Route extends RouteDef > = Simplify <
47
- {
48
- route : ReplacePathParams < Route [ "route" ] >
49
- } & Except < Route , "route" >
50
- >
64
+ export type ReplacePathParamsOnRouteDef < Route extends RouteDef > =
65
+ Route extends any
66
+ ? Simplify <
67
+ {
68
+ route : ReplacePathParams < Route [ "route" ] >
69
+ } & Except < Route , "route" >
70
+ >
71
+ : never
51
72
52
73
export type AnyRoutePath < Routes extends RouteDef > = Routes [ "route" ]
53
74
54
- // Given a path and a method, widen the method type to all methods accepted for that path
55
- export type WidenConcreteMethod <
56
- Routes extends RouteDef ,
57
- Path extends AnyRoutePath < Routes > ,
58
- Method extends HTTPMethod
59
- > = Extract < Routes , { route : Path } > extends infer Route
60
- ? Route extends RouteDef
61
- ? Method extends Route [ "method" ]
62
- ? Route [ "method" ]
63
- : never
64
- : never
65
- : never
66
-
67
75
export type PathWithMethod <
68
76
Routes extends RouteDef ,
69
77
Method extends HTTPMethod
70
- > = Extract <
71
- Routes ,
72
- { method : WidenConcreteMethod < Routes , AnyRoutePath < Routes > , Method > }
73
- > [ "route" ]
78
+ > = Extract < Routes , { method : Method } > [ "route" ]
74
79
75
80
export type MatchingRouteByPath <
76
81
Routes extends RouteDef ,
@@ -87,17 +92,15 @@ export type MatchingRoute<
87
92
Routes extends RouteDef ,
88
93
Path extends AnyRoutePath < Routes > ,
89
94
Method extends HTTPMethod = HTTPMethod
90
- > = Extract <
91
- Routes ,
92
- {
93
- route : WidenConcretePathParams < Path , Routes >
94
- method : WidenConcreteMethod <
95
- Routes ,
96
- WidenConcretePathParams < Path , Routes > ,
97
- Method
98
- >
99
- }
100
- >
95
+ > = Routes extends infer Route
96
+ ? Route extends RouteDef
97
+ ? Split < Path , "/" > extends Split < Route [ "route" ] , "/" >
98
+ ? Route [ "method" ] extends Method
99
+ ? Route
100
+ : never
101
+ : never
102
+ : never
103
+ : never
101
104
102
105
export type RouteResponse <
103
106
Routes extends RouteDef ,
@@ -141,7 +144,9 @@ export type ExtendedAxiosRequestConfigForMethod<
141
144
142
145
export interface TypedAxios <
143
146
T extends APIDef ,
144
- Routes extends RouteDef = ReplacePathParamsOnRouteDef < APIDefToUnion < T > >
147
+ Routes extends RouteDef = ExplodeMethodsOnRouteDef <
148
+ ReplacePathParamsOnRouteDef < APIDefToUnion < T > >
149
+ >
145
150
> {
146
151
defaults : AxiosInstance [ "defaults" ]
147
152
interceptors : AxiosInstance [ "interceptors" ]
0 commit comments