@@ -161,40 +161,39 @@ export interface DataRouteObject extends RouteObject {
161
161
id : string ;
162
162
}
163
163
164
- type Star = "*" ;
164
+ // Recursive helper for finding path parameters in the absence of wildcards
165
+ type _PathParam < Path extends string > =
166
+ // split path into individual path segments
167
+ Path extends `${infer L } /${infer R } ` ? _PathParam < L > | _PathParam < R > :
168
+ // find params after `:`
169
+ Path extends `${string } :${infer Param } ` ? Param :
170
+ // otherwise, there aren't any params present
171
+ never
172
+
165
173
/**
166
- * @private
167
- * Return string union from path string.
168
- * @example
169
- * PathParam<"/path/:a/:b"> // "a" | "b"
170
- * PathParam<"/path/:a/:b/*"> // "a" | "b" | "*"
174
+ * Examples:
175
+ * "/a/b/*" -> "*"
176
+ * ":a" -> "a"
177
+ * "/a/:b" -> "b"
178
+ * "/a/blahblahblah:b" -> "b"
179
+ * "/:a/:b" -> "a" | "b"
180
+ * "/:a/b/:c/*" -> "a" | "c" | "*"
171
181
*/
172
182
type PathParam < Path extends string > =
173
- // Check path string starts with slash and a param string.
174
- Path extends `:${infer Param } /${infer Rest } `
175
- ? Param | PathParam < Rest >
176
- : // Check path string is a param string.
177
- Path extends `:${infer Param } `
178
- ? Param
179
- : // Check path string ends with slash and a param string.
180
- Path extends `${any } /:${infer Param } `
181
- ? PathParam < `:${Param } `>
182
- : // Check path string ends with slash and a star.
183
- Path extends `${any } /${Star } `
184
- ? Star
185
- : // Check string is star.
186
- Path extends Star
187
- ? Star
188
- : never ;
183
+ // check if path is just a wildcard
184
+ Path extends "*" ? "*" :
185
+ // look for wildcard at the end of the path
186
+ Path extends `${infer Rest } /*` ? "*" | _PathParam < Rest > :
187
+ // look for params in the absence of wildcards
188
+ _PathParam < Path >
189
189
190
190
// Attempt to parse the given string segment. If it fails, then just return the
191
191
// plain string type as a default fallback. Otherwise return the union of the
192
192
// parsed string literals that were referenced as dynamic segments in the route.
193
- export type ParamParseKey < Segment extends string > = [
193
+ export type ParamParseKey < Segment extends string > =
194
+ // if could not find path params, fallback to `string`
195
+ [ PathParam < Segment > ] extends [ never ] ? string :
194
196
PathParam < Segment >
195
- ] extends [ never ]
196
- ? PathParam < Segment >
197
- : string ;
198
197
199
198
/**
200
199
* The parameters that were parsed from the URL path.
0 commit comments