Skip to content

refactor(web): port the docs type generator to the typescript 7 api - #574

Merged
kianbazza merged 1 commit into
ui-437-adopt-typescript-7-for-type-checking-with-hybrid-ts-5-pinsfrom
ui-627-port-the-docs-type-generator-to-the-typescript-7-api
Sep 29, 2026
Merged

kianbazza merged 1 commit into
ui-437-adopt-typescript-7-for-type-checking-with-hybrid-ts-5-pinsfrom
ui-627-port-the-docs-type-generator-to-the-typescript-7-api

Conversation

@kianbazza

@kianbazza kianbazza commented Sep 29, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

 build-types-meta.ts
-import ts from 'typescript5'                     # TS 5 compiler API
+import { API, … } from 'typescript/unstable/sync' # TS 7 API (talks to the Go checker)
+import { isInterfaceDeclaration, … } from 'typescript/unstable/ast'

 main
-  ts.createProgram({ rootNames, options })
+  new API() → write .tsconfig.types-meta.<pid>.json (extends --tsconfig, files = entries)
+            → updateSnapshot({ openProjects }) → project.program / project.checker
+  finally: api.close(), remove the temp tsconfig

 apps/web/package.json
-  "typescript5": "npm:typescript@5.9.3"

The generator's logic and output schema are unchanged. What changed is how it reaches TypeScript. TypeScript 7 has no classic compiler API; its checker runs in a separate process that typescript/unstable/sync talks to. The port maps each call across:

  • Declarations come back as handles that resolve to AST nodes.
  • Docs and JSDoc tags come back as strings.
  • typeToString takes the TypeFormatFlags values as numbers, since TS 7 doesn't export the enum.
  • Diagnostics are formatted locally.

The analysis project is a throwaway tsconfig next to apps/web/tsconfig.json, so extends, paths and type roots resolve as before. It's gitignored and removed on exit, on failure, and on Ctrl-C.

Three places reproduce TypeScript 5 behaviour that TypeScript 7 doesn't share, so the docs tables stay the same:

  • Prop order. TS 7 lists an interface's inherited props first. propertyOrder restores TS 5's order: the interface's own members in source order, then each base in extends order.
  • Inherited descriptions. An undocumented prop that redeclares an inherited one takes the base's docs, using TS 5's rule. For example, DropdownMenuRootProps.children keeps Base UI's Popover description.
  • Type definitions. These are printed from source text, because TS 7's printer drops comments. For example, ColumnDataType's annotated union.

Evidence

  • Before: bun run docs:type-gen needs typescript5 (TypeScript 5.9.3) next to TypeScript 7.
    After: it runs on TypeScript 7 only, in about 3 s (same as before), and produces identical output on repeated runs.
  • types-meta.json was compared against the previous generator's output on the same sources. Union and intersection members were compared as sets and everything else in order:
    • The same 490 types and 2,151 props. required, default, shortType, enum members and their valueType, typeParams and type docs are all identical. No union member or argument changed.
    • 393 type/formattedType strings differ only in union member order: TS 7 orders unions differently, e.g. ((props, state) => ReactElement) | ReactElement.
    • 45 definitions now use source formatting: repo indentation, no semicolons, comments kept.
    • 29 tables list props in a different order. All of them are Pick/Omit-derived types such as CheckboxItemDef, ComboboxSurfaceProps, SelectSurfaceProps and the registry Filter*Props, where TS 5's order was effectively arbitrary. Component *Props tables like DropdownMenuItemProps and ComboboxItemProps are unchanged.
    • 4 *SurfaceProps.children now show "Children (Input, List, etc.)" where they had no description.
    • 3 "View …" links move because they follow the first member of a union: BreadcrumbNode.node, and content on DropdownMenuSurfaceProps / SelectSurfaceProps.

Merge Danger

Door: two-way

Revert to restore the TS 5 generator (and re-add the typescript5 alias).

Blast Radius: docs type tables

The docs render types-meta.json directly, so the order and description changes above are visible on the component API pages. typescript/unstable/* can change in any TypeScript release; typescript is pinned to 7.0.2 exactly, and a TypeScript bump should re-run docs:type-gen and diff the output.

Closes UI-627

@kianbazza
kianbazza added this pull request to stack #570 September 29, 2026 14:31
@vercel

vercel Bot commented Sep 29, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
ui-canary Ready Ready Preview Sep 29, 2026 2:55pm UTC

Request Review

@linear-code

linear-code Bot commented Sep 29, 2026

Copy link
Copy Markdown

UI-627

Moves `apps/web/scripts/build-types-meta.ts` from the TypeScript 5 compiler API to TypeScript 7's `typescript/unstable/sync` API and drops the `typescript5` alias, so the repo carries one TypeScript version. Regenerates `apps/web/.types/types-meta.json`; the extracted types, props, and docs match the previous output apart from union ordering and a few noted differences.
@kianbazza
kianbazza force-pushed the ui-627-port-the-docs-type-generator-to-the-typescript-7-api branch from 01944cd to ad6f2b2 Compare September 29, 2026 14:54
@kianbazza
kianbazza marked this pull request as ready for review September 29, 2026 14:58
@kianbazza
kianbazza merged commit fd3662a into canary Sep 29, 2026
5 of 8 checks passed

This branch was successfully deployed

1 active deployment
Preview – ui-canary — ad6f2b28 Deployed Sep 29, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant