|
| 1 | +--- |
| 2 | +"@react-router/dev": minor |
| 3 | +"react-router": minor |
| 4 | +--- |
| 5 | + |
| 6 | +### Typesafety improvements |
| 7 | + |
| 8 | +React Router now generates types for each of your route modules. |
| 9 | +You can access those types by importing them from `./+types/<route filename without extension>`. |
| 10 | +For example: |
| 11 | + |
| 12 | +```ts |
| 13 | +// app/routes/product.tsx |
| 14 | +import type * as Route from "./+types/product"; |
| 15 | + |
| 16 | +export function loader({ params }: Route.LoaderArgs) {} |
| 17 | + |
| 18 | +export default function Component({ loaderData }: Route.ComponentProps) {} |
| 19 | +``` |
| 20 | + |
| 21 | +This initial implementation targets type inference for: |
| 22 | + |
| 23 | +- `Params` : Path parameters from your routing config in `routes.ts` including file-based routing |
| 24 | +- `LoaderData` : Loader data from `loader` and/or `clientLoader` within your route module |
| 25 | +- `ActionData` : Action data from `action` and/or `clientAction` within your route module |
| 26 | + |
| 27 | +These types are then used to create types for route export args and props: |
| 28 | + |
| 29 | +- `LoaderArgs` |
| 30 | +- `ClientLoaderArgs` |
| 31 | +- `ActionArgs` |
| 32 | +- `ClientActionArgs` |
| 33 | +- `HydrateFallbackProps` |
| 34 | +- `ComponentProps` (for the `default` export) |
| 35 | +- `ErrorBoundaryProps` |
| 36 | + |
| 37 | +In the future, we plan to add types for the rest of the route module exports: `meta`, `links`, `headers`, `shouldRevalidate`, etc. |
| 38 | +We also plan to generate types for typesafe `Link`s: |
| 39 | + |
| 40 | +```tsx |
| 41 | +<Link to="/products/:id" params={{ id: 1 }} /> |
| 42 | +// ^^^^^^^^^^^^^ ^^^^^^^^^ |
| 43 | +// typesafe `to` and `params` based on the available routes in your app |
| 44 | +``` |
| 45 | + |
| 46 | +#### Setup |
| 47 | + |
| 48 | +React Router will generate types into a `.react-router/` directory at the root of your app. |
| 49 | +This directory is fully managed by React Router and is derived based on your route config (`routes.ts`). |
| 50 | + |
| 51 | +👉 ** Add `.react-router/` to `.gitignore` ** |
| 52 | + |
| 53 | +```txt |
| 54 | +.react-router |
| 55 | +``` |
| 56 | + |
| 57 | +You should also ensure that generated types for routes are always present before running typechecking, |
| 58 | +especially for running typechecking in CI. |
| 59 | + |
| 60 | +👉 ** Add `react-router typegen` to your `typecheck` command in `package.json` ** |
| 61 | + |
| 62 | +```json |
| 63 | +{ |
| 64 | + "scripts": { |
| 65 | + "typecheck": "react-router typegen && tsc" |
| 66 | + } |
| 67 | +} |
| 68 | +``` |
| 69 | + |
| 70 | +To get TypeScript to use those generated types, you'll need to add them to `include` in `tsconfig.json`. |
| 71 | +And to be able to import them as if they files next to your route modules, you'll also need to configure `rootDirs`. |
| 72 | + |
| 73 | +👉 ** Configure `tsconfig.json` for generated types ** |
| 74 | + |
| 75 | +```json |
| 76 | +{ |
| 77 | + "include": [".react-router/types/**/*"], |
| 78 | + "compilerOptions": { |
| 79 | + "rootDirs": [".", "./.react-router/types"] |
| 80 | + } |
| 81 | +} |
| 82 | +``` |
| 83 | + |
| 84 | +#### `typegen` command |
| 85 | + |
| 86 | +You can manually generate types with the new `typegen` command: |
| 87 | + |
| 88 | +```sh |
| 89 | +react-router typegen |
| 90 | +``` |
| 91 | + |
| 92 | +However, manual type generation is tedious and types can get out of sync quickly if you ever forget to run `typegen`. |
| 93 | +Instead, we recommend that you setup our new TypeScript plugin which will automatically generate fresh types whenever routes change. |
| 94 | +That way, you'll always have up-to-date types. |
| 95 | + |
| 96 | +#### TypeScript plugin |
| 97 | + |
| 98 | +To get automatic type generation, you can use our new TypeScript plugin. |
| 99 | + |
| 100 | +👉 ** Add the TypeScript plugin to `tsconfig.json` ** |
| 101 | + |
| 102 | +```json |
| 103 | +{ |
| 104 | + "compilerOptions": { |
| 105 | + "plugins": [{ "name": "@react-router/dev" }] |
| 106 | + } |
| 107 | +} |
| 108 | +``` |
| 109 | + |
| 110 | +We plan to add some other goodies to our TypeScript plugin soon, including: |
| 111 | + |
| 112 | +- Automatic `jsdoc` for route exports that include links to official docs |
| 113 | +- Autocomplete for route exports |
| 114 | +- Warnings for non-HMR compliant exports |
| 115 | + |
| 116 | +##### VSCode |
| 117 | + |
| 118 | +TypeScript looks for plugins registered in `tsconfig.json` in the local `node_modules/`, |
| 119 | +but VSCode ships with its own copy of TypeScript that is installed outside of your project. |
| 120 | +For TypeScript plugins to work, you'll need to tell VSCode to use the local workspace version of TypeScript. |
| 121 | + |
| 122 | +👉 ** Ensure that VSCode is using the workspace version of TypeScript ** |
| 123 | + |
| 124 | +This should already be set up for you by a `.vscode/settings.json`: |
| 125 | + |
| 126 | +```json |
| 127 | +{ |
| 128 | + "typescript.tsdk": "node_modules/typescript/lib" |
| 129 | +} |
| 130 | +``` |
| 131 | + |
| 132 | +Alternatively, you can open up any TypeScript file and use <kbd>CMD</kbd>+<kbd>SHIFT</kbd>+<kbd>P</kbd> to find `Select TypeScript Version` and then select `Use Workspace Version`. You may need to quit VSCode and reopen it for this setting to take effect. |
| 133 | + |
| 134 | +##### Troubleshooting |
| 135 | + |
| 136 | +In VSCode, open up any TypeScript file in your project and then use <kbd>CMD</kbd>+<kbd>SHIFT</kbd>+<kbd>P</kbd> to select `Open TS Server log`. |
| 137 | +There should be a log for `[react-router] setup` that indicates that the plugin was resolved correctly. |
| 138 | +Then look for any errors in the log. |
0 commit comments