GioJSdocs
On this page

gio typegen

Write .gio/routes.d.ts and .gio/css-modules.d.ts - the typed routes and CSS import types - without starting the server.

npx gio typegen

Reference

OptionTypeDefaultDescription
-h, --helpboolean-Print the help and exit with 0. gio typegen takes no other option.

Behavior

gio typegen discovers the routes like gio routes (the .env files load first and every route.ts is imported) and writes two files under .gio/ in the project root:

  • .gio/routes.d.ts fills the global GioJS.RegisteredRoutes interface with one entry per page and route.ts pattern. That is what types href('/posts/:id', { id }), useParams(), PageProps<'/posts/:id'> and GsspContext.
  • .gio/css-modules.d.ts types *.module.css imports as class maps and allows plain *.css imports. routes.d.ts references it.

A file is rewritten only when its content changes, so the command is cheap to repeat:

text
$ npx gio typegen
gio typegen: wrote /home/me/my-app/.gio/routes.d.ts (5 routes)
$ npx gio typegen
gio typegen: /home/me/my-app/.gio/routes.d.ts is up to date (5 routes)
.gio/routes.d.ts
/// <reference path="./css-modules.d.ts" />
declare global {
  namespace GioJS {
    interface RegisteredRoutes {
      '/': Record<string, never>;
      '/about': Record<string, never>;
      '/api/notes': Record<string, never>;
      '/docs/*slug?': { slug?: string };
      '/posts/:id': { id: string };
    }
  }
}
export {};

A catch-all param is one string with / separators ("a/b"), the shape getServerSideProps receives; an optional catch-all is an optional field.

Examples

Typecheck in CI

bash
npx gio typegen && npx tsc --noEmit

The server writes these files at every start, but a CI job that only typechecks never starts it. Without the files, href() and PageProps fall back to untyped routes and CSS Module imports do not typecheck.

Include the file in tsconfig.json

tsconfig.json
{
  "include": ["app", "components", ".gio/routes.d.ts"]
}

TypeScript's wildcards skip dot-folders, so .gio/routes.d.ts must be listed by name. The starters do this; gio doctor warns when it is missing.

Good to know

  • A route.ts that fails to import in CI (it needs a secret CI does not set) is still typed, so CI and a developer machine get the same declarations.
  • WebSocket-only route.ts files and metadata routes are not in RegisteredRoutes; they are not href() targets.
  • Exit code 1 when there is no app/ directory, so a CI step run from the wrong directory fails instead of writing .gio/ elsewhere; also on a route conflict or a missing @gio.js/core.
  • Add .gio/ to .gitignore; the starters do.

Version history

VersionChanges
v0.1.0-beta.8Introduced. The declarations fill the global GioJS.RegisteredRoutes (they used to augment @gio.js/react's GioRegisteredRoutes), and css-modules.d.ts is written next to them.