Skip to content

Explore TypeScript 7 (native compiler) migration + isolatedDeclarations readiness #562

Description

@johnleider

Summary

Tracking issue for a future migration to TypeScript 7 (the native Go compiler, "Corsa"/tsgo). Captures the current readiness assessment, the actual blocker, and an isolatedDeclarations spike so the eventual move is a known quantity rather than a discovery exercise.

TL;DR: our TS config is already 7-ready, the flip is externally gated on Vue Language Tools, and the one piece of proactive prep worth scoping is isolatedDeclarations — but its payoff is deferred behind the same dependency.

What TS 7 is

The native Go rewrite of the compiler (RC as of mid-2026, GA shortly after). It ships as the standard tsc binary with ~10x faster type-checks. Type-checking semantics are a file-by-file transplant of the existing checker, so the migration risk here is toolchain, not type errors.

Current state (readiness is good)

  • Package builds go through tsdown (rolldown/oxc), not tsc — TS only does typecheck + .d.ts emit.
  • Typecheck is vue-tsc --noEmit; TS is pinned via the pnpm catalog, so the version flip is effectively a 2-line diff.
  • tsconfigs are already what the native compiler wants: moduleResolution: bundler, module/target: esnext, verbatimModuleSyntax, strict, no deprecated/removed flags. Current typecheck surfaces zero deprecation warnings.

The blocker (external)

Native tsc cannot parse .vue. That has always been Volar's job, and Volar wraps the JS TypeScript API that tsgo does not fully expose yet. Vue support is tracked upstream at vuejs/language-tools#5381. This gates both vue-tsc typecheck and the dts: { vue: true } declaration path. Nothing on our side unblocks .vue — it lands with that upstream work.

isolatedDeclarations spike

Enabling isolatedDeclarations: true on packages/0 produced 631 violations:

Surface Errors Files Fixable by us?
.ts 250 64 Yes — hand-authored
.vue 381 171 Mostly no — Volar-synthetic
  • .vue (381): ~68% are compiler-generated virtual code we cannot annotate — TS9010 on __VLS_export (×138) and TS9039 on __VLS_PublicProps (×122). Volar's emitted SFC representation isn't isolatedDeclarations-clean; this rides on the same #5381 work.
  • .ts (250): hand-fixable, dominated by two idioms — TS9016 shorthand properties can't be inferred (×163, composable return objects) and TS9019 binding elements can't be exported directly (×38, the trinity destructure-export). Remainder is method/function return types.

Because isolatedDeclarations is a single global tsconfig flag, it cannot be enabled while .vue is in the include set — so clearing the 250 .ts violations yields no turn-on-able benefit until either Volar ships clean SFC output, or .ts-only declaration emit is routed through oxc at the tsdown layer as a separate effort.

Trinity export under isolatedDeclarations (TS9019) — verified fix

The export const [a, b, c] = createTrinity(…) / createPluginContext(…) idiom (12 sites) trips TS9019. The types are already correct; the flag simply refuses to export a destructured binding and requires an explicit type on every exported const. Indexed access alone (export const useX = t[2]) does not satisfy it (→ TS9010).

Verified pattern that clears it with zero errors:

// before — trips TS9019 ×3
export const [createThemeContext, createThemePlugin, useTheme] =
  createPluginContext<ThemePluginOptions, ThemeContext>('v0:theme', /* … */)

// after — typed intermediate + indexed-access TYPE on each export
const theme: ReturnType<typeof createPluginContext<ThemePluginOptions, ThemeContext>> =
  createPluginContext<ThemePluginOptions, ThemeContext>('v0:theme', /* … */)
export const createThemeContext: (typeof theme)[0] = theme[0]
export const createThemePlugin: (typeof theme)[1] = theme[1]
export const useTheme: (typeof theme)[2] = theme[2]

Mechanical and uniform across sites, but verbose (2 lines → 5, generic args written twice). A cheaper ergonomics prep would be to export a named return-type alias from createTrinity/createPluginContext so the intermediate annotation becomes a short name instead of the ReturnType<typeof …> form.

Recommended path

  1. Don't migrate now — externally gated on TypeScript Native / TypeScript 7 (@typescript/native-preview, tsgo) Support vuejs/language-tools#5381.
  2. No config debt to pay — tsconfigs are already 7-clean.
  3. Keep TS/vue-tsc catalog-pinned so the flip stays a small diff.
  4. isolatedDeclarations is the only proactive lever, but defer the .ts cleanup: it unlocks nothing until Volar lands or we deliberately split .ts-only dts emit through oxc/tsdown (worth a separate spike).
  5. New composables can adopt the verified trinity export form to avoid growing the debt.

Follow-up candidates (separate issues if pursued)

  • Spike: can tsdown/rolldown-plugin-dts isolated-emit the .ts entries while leaving .vue on the Volar path?
  • Cheap prep: named return-type alias on createTrinity/createPluginContext.
  • Optional CI canary once #5381 shows movement.

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions