-
-
Notifications
You must be signed in to change notification settings - Fork 2.2k
Infer route parameter type from matcher's guard check if applicable #10755
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 4 commits
1d835fc
fcb6c31
8ba729e
9aceaa7
35beecf
48ad59e
385e175
6f34096
ee11e6f
a8d399e
abcc708
b7ade00
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| --- | ||
| '@sveltejs/kit': patch | ||
| --- | ||
|
|
||
| feat: infer route parameter type from matcher's guard check if applicable |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -188,10 +188,14 @@ function update_types(config, routes, route, to_delete = new Set()) { | |
| // add 'Expand' helper | ||
| // Makes sure a type is "repackaged" and therefore more readable | ||
| declarations.push('type Expand<T> = T extends infer O ? { [K in keyof O]: O[K] } : never;'); | ||
|
|
||
| //Returns the predicate of a matcher's type guard - or string if there is no type guard | ||
| declarations.push( | ||
| `type RouteParams = { ${route.params | ||
| .map((param) => `${param.name}${param.optional ? '?' : ''}: string`) | ||
| .join('; ')} }` | ||
| '//@ts-ignore\ntype MatcherParam<M> = M extends (param: string) => param is infer U ? U : string;' | ||
|
||
| ); | ||
|
|
||
| declarations.push( | ||
| 'type RouteParams = ' + generate_params_type(route.params, outdir, config) + ';' | ||
| ); | ||
|
|
||
| if (route.params.length > 0) { | ||
|
|
@@ -265,7 +269,8 @@ function update_types(config, routes, route, to_delete = new Set()) { | |
|
|
||
| if (route.layout) { | ||
| let all_pages_have_load = true; | ||
| const layout_params = new Set(); | ||
| /** @type {import('types').RouteParam[]} */ | ||
| const layout_params = []; | ||
| const ids = ['RouteId']; | ||
|
|
||
| route.layout.child_pages?.forEach((page) => { | ||
|
|
@@ -274,7 +279,9 @@ function update_types(config, routes, route, to_delete = new Set()) { | |
| if (leaf.route.page) ids.push(`"${leaf.route.id}"`); | ||
|
|
||
| for (const param of leaf.route.params) { | ||
| layout_params.add(param.name); | ||
| //Skip if already added | ||
LorisSigrist marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| if (layout_params.some((p) => p.name === param.name)) continue; | ||
| layout_params.push({ ...param, optional: true }); | ||
| } | ||
|
|
||
| ensureProxies(page, leaf.proxies); | ||
|
|
@@ -301,9 +308,7 @@ function update_types(config, routes, route, to_delete = new Set()) { | |
| declarations.push(`type LayoutRouteId = ${ids.join(' | ')}`); | ||
|
|
||
| declarations.push( | ||
| `type LayoutParams = RouteParams & { ${Array.from(layout_params).map( | ||
| (param) => `${param}?: string` | ||
| )} }` | ||
| 'type LayoutParams = RouteParams & ' + generate_params_type(layout_params, outdir, config) | ||
| ); | ||
|
|
||
| const { | ||
|
|
@@ -567,6 +572,28 @@ function replace_ext_with_js(file_path) { | |
| return file_path.slice(0, -ext.length) + '.js'; | ||
| } | ||
|
|
||
| /** | ||
| * @param {import('types').RouteParam[]} params | ||
| * @param {string} outdir | ||
| * @param {import('types').ValidatedConfig} config | ||
| */ | ||
| function generate_params_type(params, outdir, config) { | ||
| /** @param {string} matcher */ | ||
| const path_to_matcher = (matcher) => | ||
| posixify(path.relative(outdir, path.join(config.kit.files.params, matcher))); | ||
|
|
||
| return `{ ${params | ||
| .map( | ||
| (param) => | ||
| `${param.name}${param.optional ? '?' : ''}: ${ | ||
| param.matcher | ||
| ? `MatcherParam<typeof import('${path_to_matcher(param.matcher)}').match>` | ||
| : 'string' | ||
| }` | ||
| ) | ||
| .join('; ')} }`; | ||
| } | ||
|
|
||
| /** | ||
| * @param {string} content | ||
| * @param {boolean} is_server | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.