-
-
Notifications
You must be signed in to change notification settings - Fork 2.1k
feat: typed route ids #13864
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
feat: typed route ids #13864
Changes from all commits
74c0fd7
c95a69f
4fe5f0b
5669c42
3e6b274
df2293d
039fa0f
e2afa93
42ea4f8
26beba7
5865e34
e155d92
a483961
7987509
7cf2cfc
8c8c037
c6c3355
cfd16ed
c000bb4
945f9cc
9bd9a67
82d6695
6cd32d4
eb8b876
f6c4b35
c1987e0
96de94b
5a30a83
eac2a0e
5445a93
22b26dc
bb882fa
8895442
66c209d
f80faf1
a73f34a
7f5b752
de26113
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': minor | ||
--- | ||
|
||
feat: better type-safety for `page.route.id`, `page.params`, page.url.pathname` and various other places |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
--- | ||
'@sveltejs/kit': minor | ||
--- | ||
|
||
feat: `resolve(...)` and `asset(...)` helpers for resolving paths |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
--- | ||
'@sveltejs/kit': minor | ||
--- | ||
|
||
feat: Add `$app/types` module with `Asset`, `RouteId`, `Pathname`, `ResolvedPathname` `RouteParams<T>` and `LayoutParams<T>` |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,91 @@ | ||
--- | ||
title: $app/types | ||
--- | ||
|
||
This module contains generated types for the routes in your app. | ||
|
||
<blockquote class="since note"> | ||
<p>Available since 2.26</p> | ||
</blockquote> | ||
|
||
```js | ||
// @noErrors | ||
import type { RouteId, RouteParams, LayoutParams } from '$app/types'; | ||
``` | ||
|
||
## Asset | ||
|
||
A union of all the filenames of assets contained in your `static` directory. | ||
|
||
<div class="ts-block"> | ||
|
||
```dts | ||
type Asset = '/favicon.png' | '/robots.txt'; | ||
``` | ||
|
||
</div> | ||
|
||
## RouteId | ||
|
||
A union of all the route IDs in your app. Used for `page.route.id` and `event.route.id`. | ||
|
||
<div class="ts-block"> | ||
|
||
```dts | ||
type RouteId = '/' | '/my-route' | '/my-other-route/[param]'; | ||
``` | ||
|
||
</div> | ||
|
||
## Pathname | ||
|
||
A union of all valid pathnames in your app. | ||
|
||
<div class="ts-block"> | ||
|
||
```dts | ||
type Pathname = '/' | '/my-route' | `/my-other-route/${string}` & {}; | ||
``` | ||
|
||
</div> | ||
|
||
## ResolvedPathname | ||
|
||
`Pathname`, but possibly prefixed with a [base path](https://svelte.dev/docs/kit/configuration#paths). Used for `page.url.pathname`. | ||
|
||
<div class="ts-block"> | ||
|
||
```dts | ||
type Pathname = `${'' | `/${string}`}/` | `${'' | `/${string}`}/my-route` | `${'' | `/${string}`}/my-other-route/${string}` | {}; | ||
``` | ||
|
||
</div> | ||
|
||
## RouteParams | ||
|
||
A utility for getting the parameters associated with a given route. | ||
|
||
```ts | ||
// @errors: 2552 | ||
type BlogParams = RouteParams<'/blog/[slug]'>; // { slug: string } | ||
``` | ||
|
||
<div class="ts-block"> | ||
|
||
```dts | ||
type RouteParams<T extends RouteId> = { /* generated */ } | Record<string, never>; | ||
Rich-Harris marked this conversation as resolved.
Show resolved
Hide resolved
|
||
``` | ||
|
||
</div> | ||
|
||
## LayoutParams | ||
|
||
A utility for getting the parameters associated with a given layout, which is similar to `RouteParams` but also includes optional parameters for any child route. | ||
|
||
<div class="ts-block"> | ||
|
||
```dts | ||
type RouteParams<T extends RouteId> = { /* generated */ } | Record<string, never>; | ||
``` | ||
|
||
</div> |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -7,7 +7,8 @@ | |
"target": "es2022", | ||
"module": "node16", | ||
"moduleResolution": "node16", | ||
"baseUrl": "." | ||
"baseUrl": ".", | ||
"skipLibCheck": true | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
EDIT: Alright, I'm seeing the errors now. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm thinking of looking into There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Worth a shot I guess, though dts-buddy is operating on emitted declaration files and I'm pretty sure the comments are lost by that point - might be tricky to correctly recover them from the source There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I managed to get it working in sveltejs/dts-buddy#110 . This should remove the need for the hack in The ts-ignore is only preserved if it meets these two rules:
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ah nice. I don't have time to review that PR right now but I left a comment over there to remind myself to come back and clean this up later |
||
}, | ||
"include": ["**/*.js"] | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,5 @@ | ||
import { createBundle } from 'dts-buddy'; | ||
import { readFileSync } from 'node:fs'; | ||
import { readFileSync, writeFileSync } from 'node:fs'; | ||
|
||
await createBundle({ | ||
output: 'types/index.d.ts', | ||
|
@@ -28,3 +28,9 @@ if (types.includes('__sveltekit/')) { | |
types | ||
); | ||
} | ||
|
||
// this is hacky as all hell but it gets the tests passing. might be a bug in dts-buddy? | ||
// prettier-ignore | ||
writeFileSync('./types/index.d.ts', types.replace("declare module '$app/server' {", `declare module '$app/server' { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. :wat: There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
// @ts-ignore | ||
import { LayoutParams as AppLayoutParams, RouteId as AppRouteId } from '$app/types'`)); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
import type { RouteId, RouteParams, Pathname } from './.svelte-kit/types/index.d.ts'; | ||
|
||
declare let id: RouteId; | ||
|
||
// okay | ||
id = '/'; | ||
id = '/foo/[bar]/[baz]'; | ||
|
||
// @ts-expect-error | ||
id = '/nope'; | ||
|
||
// read `id` otherwise it is treated as unused | ||
id; | ||
elliott-with-the-longest-name-on-github marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
declare let params: RouteParams<'/foo/[bar]/[baz]'>; | ||
|
||
// @ts-expect-error | ||
params.foo; // not okay | ||
params.bar; // okay | ||
params.baz; // okay | ||
|
||
declare let pathname: Pathname; | ||
|
||
// @ts-expect-error | ||
pathname = '/nope'; | ||
pathname = '/foo'; | ||
pathname = '/foo/1/2'; | ||
|
||
// read `pathname` otherwise it is treated as unused | ||
pathname; | ||
elliott-with-the-longest-name-on-github marked this conversation as resolved.
Show resolved
Hide resolved
|
Uh oh!
There was an error while loading. Please reload this page.