@@ -75,25 +75,25 @@ export type RequestInitT<
75
75
/**
76
76
* FetchT is a type for window.fetch like function but more strict type information
77
77
*
78
- * @template UrlPrefix - url prefix of `Input`
78
+ * @template UrlPrefix - URL prefix of `Input`
79
79
* For example, if `UrlPrefix` is "https://example.com", then `Input` must be `https://example.com/${string}`
80
80
*
81
81
* @template E - ApiEndpoints
82
82
* E is used to infer the type of the acceptable path, response body, and more
83
83
*/
84
84
type FetchT < UrlPrefix extends UrlPrefixPattern , E extends ApiEndpoints > = <
85
85
/**
86
- * internal type for FetchT
86
+ * Internal type for FetchT
87
87
* They are not supposed to be specified by the user
88
88
*
89
- * @template UrlPattern - Acceptable url pattern
90
- * For example, if endpoints is defined as below:
89
+ * @template UrlPattern - Acceptable URL pattern
90
+ * For example, if endpoints are defined as below:
91
91
* { "/users": ..., "/users/:userId": ... }
92
92
* and UrlPrefix is "https://example.com",
93
93
* then UrlPattern will be "https://example.com/users" | "https://example.com/users/${string}"
94
94
*
95
95
* @template Input - Input of the request by the user
96
- * For example, if endpoints is defined as below:
96
+ * For example, if endpoints are defined as below:
97
97
* { "/users": ..., "/users/:userId": ... }
98
98
* then Input accepts "https://example.com/users" | "https://example.com/users/${string}"
99
99
* If query is defined in the spec, Input also accepts "https://example.com/users?${string}" | "https://example.com/users/${string}?${string}"
@@ -102,27 +102,39 @@ type FetchT<UrlPrefix extends UrlPrefixPattern, E extends ApiEndpoints> = <
102
102
* For example, if Input is "https://example.com/users/1", then InputPath will be "/users/${string}"
103
103
*
104
104
* @template CandidatePaths - Matched paths from `InputPath` and `keyof E`
105
- * For example, if InputPath is "/users/1" and endpoints is defined as below:
105
+ * For example, if InputPath is "/users/1" and endpoints are defined as below:
106
106
* { "/users": ..., "/users/:userId": ... }
107
107
* then CandidatePaths will be "/users/:userId"
108
108
* If no matched path is found, CandidatePaths will be never
109
- * If multiple matched paths are found, CandidatePaths will be union of matched paths
109
+ * If multiple matched paths are found, CandidatePaths will be a union of matched paths
110
110
*
111
111
* @template AcceptableMethods - Acceptable methods for the matched path
112
- * For example, if CandidatePaths is "/users/:userId" and endpoints is defined as below:
112
+ * For example, if CandidatePaths is "/users/:userId" and endpoints are defined as below:
113
113
* { "/users": { get: ... }, "/users/:userId": { get: ..., post: ... } }
114
114
* then AcceptableMethods will be "get" | "post"
115
115
*
116
- * @template LM - Lowercase of `InputMethod`
116
+ * @template LM - Lowercase version of `InputMethod`
117
117
*
118
- * @template Query - Query object of endpoint which is matched with `CandidatePaths`
118
+ * @template Query - Query object of the endpoint that matches `CandidatePaths`
119
119
*
120
- * @template ResBody - Response body of the endpoint which is matched with `CandidatePaths`
120
+ * @template Headers - Request headers object of the endpoint
121
121
*
122
- * @template InputMethod - Method of the request specified by the user
122
+ * @template Body - Request body object of the endpoint
123
+ *
124
+ * @template Response - Response object of the endpoint that matches `CandidatePaths`
125
+ *
126
+ * @template ValidatedUrl - Result of URL validation
127
+ *
128
+ * @template InputMethod - Method of the request as specified by the user
123
129
* For example, if `fetch` is called with `fetch("https://example.com/users", { method: "post" })`,
124
130
* then InputMethod will be "post".
125
131
* If `get` method is defined in the spec, method can be omitted, and it will be `get` by default
132
+ *
133
+ * @template CanOmitMethod - Whether the method property in the "init" parameter can be omitted
134
+ * If the endpoint defines a "get" method, then the method can be omitted
135
+ *
136
+ * @template CanOmitInit - Whether the "init" parameter can be omitted for the request
137
+ * If the method can be omitted (`CanOmitMethod` is true) and the endpoint does not require headers, then the "init" parameter can be omitted
126
138
*/
127
139
UrlPattern extends ToUrlParamPattern < `${UrlPrefix } ${keyof E & string } `> ,
128
140
Input extends Query extends undefined
@@ -141,6 +153,8 @@ type FetchT<UrlPrefix extends UrlPrefixPattern, E extends ApiEndpoints> = <
141
153
: never ,
142
154
LM extends Lowercase < InputMethod > ,
143
155
Query extends ApiP < E , CandidatePaths , LM , "query" > ,
156
+ Headers extends ApiP < E , CandidatePaths , LM , "headers" > ,
157
+ Body extends ApiP < E , CandidatePaths , LM , "body" > ,
144
158
Response extends ApiP <
145
159
E ,
146
160
CandidatePaths ,
@@ -154,17 +168,25 @@ type FetchT<UrlPrefix extends UrlPrefixPattern, E extends ApiEndpoints> = <
154
168
AcceptableMethods ,
155
169
"get"
156
170
> ,
171
+ CanOmitMethod extends boolean = "get" extends AcceptableMethods
172
+ ? true
173
+ : false ,
174
+ CanOmitInit extends boolean = CanOmitMethod extends true
175
+ ? Headers extends undefined
176
+ ? true
177
+ : Headers extends Record < string , string >
178
+ ? IsAllOptional < Headers > extends true
179
+ ? true
180
+ : false
181
+ : false
182
+ : false ,
157
183
> (
158
184
input : [ ValidatedUrl ] extends [ C . OK | QueryParameterRequiredError ]
159
185
? Input
160
186
: ValidatedUrl ,
161
- init : RequestInitT <
162
- // If `get` method is defined in the spec, method can be omitted
163
- "get" extends AcceptableMethods ? true : false ,
164
- ApiP < E , CandidatePaths , LM , "body" > ,
165
- ApiP < E , CandidatePaths , LM , "headers" > ,
166
- InputMethod
167
- > ,
187
+ ...args : CanOmitInit extends true
188
+ ? [ init ?: RequestInitT < CanOmitMethod , Body , Headers , InputMethod > ]
189
+ : [ init : RequestInitT < CanOmitMethod , Body , Headers , InputMethod > ]
168
190
) => Promise < Response > ;
169
191
170
192
export default FetchT ;
0 commit comments