diff --git a/docs/guide/typescript.md b/docs/guide/typescript.md index a33dee239..791accc6a 100644 --- a/docs/guide/typescript.md +++ b/docs/guide/typescript.md @@ -33,25 +33,43 @@ router.push('') ## Extra types -You can always take a look at the generated `typed-router.d.ts` file to inspect what are the generated types. `unplugin-vue-router` creates a `RouteNamedMap` interface and exports it from `'vue-router/auto-routes'`. +### `typed-router.d.ts` contents +You can always take a look at the generated `typed-router.d.ts` file to inspect what are the generated types. `unplugin-vue-router` creates and exports interfaces and helper types from `'vue-router/auto-routes'`: +- `RouteNamedMap` interface +- `_RouteFileInfoMap` interface +- `_RouteNamesForFilePath` helper type +#### `RouteNamedMap` +This interface maps route names to “route records”, containing the types for each route. A route record includes a route’s name, path, typed params and a list of its child route names. + +#### `_RouteFileInfoMap` +This interface is used by the [`sfc-typed-router` Volar plugin](#using-the-sfc-typed-router-volar-plugin), if enabled. It maps page component file paths to all route names and views that could be displayed within these components. + +#### `_RouteNamesForFilePath` +This is a helper type, used by the [`sfc-typed-router` Volar plugin](#using-the-sfc-typed-router-volar-plugin) to enhance typings for `useRoute()` and `$route`, if enabled. It returns the route names corresponding to a page component’s file path, or falls back to `keyof RouteNamedMap` in non-page components. + +### Manually typing dynamically added routes ```ts import type { RouteNamedMap } from 'vue-router/auto-routes' ``` -This interface contains all the routes in your application along with their metadata. Augment it to add types for **dynamic routes** that are added during runtime: +The `RouteNamedMap` interface contains all the routes in your application along with their metadata. You can augment it to add types for **dynamic routes** that are added during runtime. + +Note that, if you are using the [`sfc-typed-router` Volar plugin](#using-the-sfc-typed-router-volar-plugin), you should also augment the `_RouteFileInfoMap` interface for every dynamically added route corresponding to a page component. ```ts export {} // needed in .d.ts files -import type { - RouteRecordInfo, - ParamValue, - // these are other param helper types - ParamValueOneOrMore, - ParamValueZeroOrMore, - ParamValueZeroOrOne, -} from 'vue-router' + declare module 'vue-router/auto-routes' { + import type { + RouteRecordInfo, + ParamValue, + // these are other param helper types + ParamValueOneOrMore, + ParamValueZeroOrMore, + ParamValueZeroOrOne, + } from 'vue-router' + export interface RouteNamedMap { // the key is the name and should match the first generic of RouteRecordInfo 'custom-dynamic-name': RouteRecordInfo< @@ -73,10 +91,25 @@ declare module 'vue-router/auto-routes' { never > } + + export interface _RouteFileInfoMap { + // the key is the file path and should match the page component's file path + '/added-during-runtime/[...path].vue': { + // these are the route names that can be displayed within this component + routes: 'custom-dynamic-name' | 'custom-dynamic-child-name' + // these are the views that can be used in this file + views: 'default' + } + + '/added-during-runtime/[...path]/child.vue': { + routes: 'custom-dynamic-child-name' + views: never + } + } } ``` -You can now pass a _type param_ to the generic route location types to narrow down the type of the route: +You can now pass a _type param_ to the generic route location types to narrow down the type of the route. This automatically includes any child routes typings as well: ```ts twoslash // ---cut-start--- @@ -87,19 +120,55 @@ import { useRoute, type RouteLocationNormalizedLoaded } from 'vue-router' // @errors: 2322 2339 // @moduleResolution: bundler // These are all valid ways to get a typed route and return the -// provided route's and any of its child routes' typings. +// provided route’s and any of its child routes’ typings. // Note that `/users/[id]/edit` is a child route // of `/users/[id]` in this example. -// Not recommended, since this leaves out any child routes' typings. +// Not recommended, since this leaves out any child routes’ typings. const userRouteWithIdCasted = useRoute() as RouteLocationNormalizedLoaded<'/users/[id]'> userRouteWithIdCasted.params.id -// Better way, but no autocompletion. + +// Better way. Includes child routes’ typings, but no autocompletion. const userRouteWithIdTypeParam = useRoute<'/users/[id]'>() userRouteWithIdTypeParam.params.id -// 👇 This one is the easiest to write because it autocompletes. + +// 👇 This one is the easiest to write because it both +// autocompletes and includes child routes’ typings. const userRouteWithIdParam = useRoute('/users/[id]') userRouteWithIdParam.name -// ^? +userRouteWithIdParam.params.id ``` + +### Using the `sfc-typed-router` Volar plugin +This Volar plugin automatically types `useRoute()` and `$route` correctly in page components, so you don’t have to write code like `useRoute('/users/[id]')`, allowing you to write less code. + +To start using the plugin, add the following to the `tsconfig.json` file that includes your Vue files: +```json +{ + // ... + "vueCompilerOptions": { + "plugins": [ + "unplugin-vue-router/volar/sfc-typed-router" + ] + } +} +``` + +As long as this plugin isn’t enabled in Nuxt by default with `experimental.typedPages: true` or through any other experimental feature flag, you should manually add the plugin via `nuxt.config.ts`: +```ts +export default defineNuxtConfig({ + // ... + typescript: { + tsConfig: { + vueCompilerOptions: { + plugins: [ + 'unplugin-vue-router/volar/sfc-typed-router', + ], + }, + }, + }, +}) +``` + +When using the `sfc-typed-router` Volar plugin, `useRoute()` and `$route` are typed automatically for page components under the hood, so you don’t have to do it manually. \ No newline at end of file diff --git a/docs/nuxt/getting-started.md b/docs/nuxt/getting-started.md index 8674a2bfa..c98493264 100644 --- a/docs/nuxt/getting-started.md +++ b/docs/nuxt/getting-started.md @@ -1,6 +1,6 @@ # Nuxt -Currently, this plugin is included as an experimental setting in Nuxt. You can enable it by adding the following to your `nuxt.config.js`: +Currently, this plugin is included as an experimental setting in Nuxt. You can enable it by adding the following to your `nuxt.config.ts`: ```ts{2-4} export default defineNuxtConfig({ @@ -9,3 +9,5 @@ export default defineNuxtConfig({ }, }) ``` + +The `sfc-typed-router` Volar plugin, that automatically types `useRoute()` and `$route` in page components, cannot be enabled using a feature flag in Nuxt at this time. Read how to enable it here: [Using the `sfc-typed-router` Volar plugin](/guide/typescript#using-the-sfc-typed-router-volar-plugin). \ No newline at end of file