Skip to content

Commit de9e0cc

Browse files
authored
fix: restore and deprecate $params helper for incremental migrations (#142)
* chore: restore and deprecate $params helper for incremental migrations * update snapshots
1 parent 6732df0 commit de9e0cc

File tree

5 files changed

+56
-1
lines changed

5 files changed

+56
-1
lines changed

README.md

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,31 @@ export const loader = async (request) => {
121121
}
122122
```
123123

124+
### Checking params
125+
126+
> [!NOTE]
127+
> This function has been marked `@deprecated` in favor of React Router's
128+
> built-in type-safety, which provides strongly typed `params` to loaders,
129+
> actions, and components. This helper has been kept primarily to assist in
130+
> incremental migration.
131+
132+
```typescript
133+
import { useParams } from "react-router";
134+
import { $params } from 'safe-routes'; // <-- Import $params helper.
135+
136+
export const action = async ({ params }) => {
137+
const { id } = $params("/posts/:id/update", params) // <-- It's type safe, try renaming `id` param.
138+
139+
// ...
140+
}
141+
142+
export default function Component() {
143+
const params = useParams();
144+
const { id } = $params("/posts/:id/update", params);
145+
...
146+
}
147+
```
148+
124149
### Typed route ids
125150

126151
safe-routes exports the `RouteId` type definition with the list of all valid route ids for your repository, and has a helper function `$routeId` that tells typescript to restrict the given string to one of the valid RouteId values.

src/index.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,3 +58,11 @@ export function $path(route: string, ...paramsOrQuery: Array<any>) {
5858
export function $routeId(routeId: string) {
5959
return routeId;
6060
}
61+
62+
/** @deprecated Prefer to use React Router's typegen features instead. */
63+
export function $params(
64+
_route: string,
65+
params: { readonly [key: string]: string | undefined },
66+
) {
67+
return params;
68+
}

src/template.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,5 +70,14 @@ export function template(ctx: Context) {
7070
): string;
7171
7272
export function $routeId(routeId: RouteId): RouteId;
73+
74+
/** @deprecated Prefer to use React Router's typegen features instead. */
75+
export function $params<
76+
Route extends keyof RoutesWithParams,
77+
Params extends RoutesWithParams[Route]["params"]
78+
>(
79+
route: Route,
80+
params: { readonly [key: string]: string | undefined }
81+
): {[K in keyof Params]: string};
7382
}`;
7483
};

tests/__snapshots__/build.test.ts.snap

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,5 +186,14 @@ exports[`gen route types 1`] = `
186186
): string;
187187
188188
export function $routeId(routeId: RouteId): RouteId;
189+
190+
/** @deprecated Prefer to use React Router's typegen features instead. */
191+
export function $params<
192+
Route extends keyof RoutesWithParams,
193+
Params extends RoutesWithParams[Route]["params"]
194+
>(
195+
route: Route,
196+
params: { readonly [key: string]: string | undefined }
197+
): {[K in keyof Params]: string};
189198
}"
190199
`;

tests/index.test.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { expect, test, vi } from 'vitest';
2-
import { $path } from '../src';
2+
import { $params, $path } from '../src';
33
import * as basename from '../src/basename.ts';
44

55
vi.mock(import('../src/basename.ts'));
@@ -53,6 +53,10 @@ test('optional segment', () => {
5353
expect($path('/tree?/:tree?', { tree: 'main' })).toBe('/tree/main');
5454
});
5555

56+
test('$params', () => {
57+
expect($params('/posts/:id', { id: '1' })).toStrictEqual({ id: '1' });
58+
});
59+
5660
test('basename', async () => {
5761
vi.mocked(basename.resolveBasename).mockReturnValue('/blog');
5862

0 commit comments

Comments
 (0)