Skip to content

Commit a24c402

Browse files
committed
improve generatePath arg type
1 parent 92aa5bb commit a24c402

File tree

2 files changed

+41
-4
lines changed

2 files changed

+41
-4
lines changed

docs/utils/generate-path.md

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,26 @@ title: generatePath
88
<summary>Type declaration</summary>
99

1010
```tsx
11-
declare function generatePath(
12-
path: string,
13-
params?: Params
11+
type PathParams<
12+
Path extends string
13+
> = Path extends `:${infer Param}/${infer Rest}`
14+
? Param | PathParams<Rest>
15+
: Path extends `:${infer Param}`
16+
? Param
17+
: Path extends `${any}:${infer Param}`
18+
? PathParams<`:${Param}`>
19+
: Path extends `${any}/*`
20+
? "*"
21+
: Path extends "*"
22+
? "*"
23+
: never
24+
25+
26+
declare function generatePath<Path extends string>(
27+
path: Path,
28+
params?: {
29+
[key in PathParams<Path> | (string & {})]: string
30+
}
1431
): string;
1532
```
1633

packages/router/utils.ts

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -441,12 +441,32 @@ function matchRouteBranch<
441441
return matches;
442442
}
443443

444+
/**
445+
* @private
446+
* Parameters in the path
447+
*/
448+
type PathParams<
449+
Path extends string
450+
> = Path extends `:${infer Param}/${infer Rest}`
451+
? Param | PathParams<Rest>
452+
: Path extends `:${infer Param}`
453+
? Param
454+
: Path extends `${any}:${infer Param}`
455+
? PathParams<`:${Param}`>
456+
: Path extends `${any}/*`
457+
? "*"
458+
: Path extends "*"
459+
? "*"
460+
: never
461+
444462
/**
445463
* Returns a path with params interpolated.
446464
*
447465
* @see https://reactrouter.com/docs/en/v6/utils/generate-path
448466
*/
449-
export function generatePath(path: string, params: Params = {}): string {
467+
export function generatePath<Path extends string>(path: Path, params: {
468+
[key in PathParams<Path> | (string & {})]: string
469+
} = {} as any): string {
450470
return path
451471
.replace(/:(\w+)/g, (_, key) => {
452472
invariant(params[key] != null, `Missing ":${key}" param`);

0 commit comments

Comments
 (0)