Skip to content

Adopt TypeScript 7 through the supported dual-compiler toolchain #97

Description

@artiphishle

Goal

Adopt TypeScript 7 as the canonical native compiler for Devtools and managed Ankhorage repositories without breaking the TypeScript compiler API consumers that still require TypeScript 6.

This must supersede Renovate PR #94. That PR only changes typescript from ~6.0.3 to ~7.0.2; it is not a valid TypeScript 7 migration.

Investigation result

PR #94 builds with TypeScript 7, then CI fails while loading the shared ESLint config:

typescript-eslint does not support TS 7.0.
Error [ERR_INTERNAL_ASSERTION]

This is expected current ecosystem behavior, not a transient Devtools lint defect:

  • TypeScript 7 is the native Go compiler and language server.
  • TypeScript 7.0 deliberately has no JavaScript compiler API. A new API is expected in 7.1.
  • typescript-eslint@8.69.0 requires the TypeScript API and declares typescript >=4.8.4 <6.1.0.
  • Microsoft therefore documents a side-by-side installation for TypeScript 7.0:
{
  "devDependencies": {
    "@typescript/native": "npm:typescript@~7.0.2",
    "typescript": "npm:@typescript/typescript6@~6.0.2"
  }
}

With the repository-pinned Bun 1.4.0, this was validated locally:

node_modules/.bin/tsc --version   -> Version 7.0.2
node_modules/.bin/tsc6 --version  -> Version 6.0.3
require('typescript').version     -> 6.0.3

The prototype passed Devtools build, lint loading, format check, Knip, 66 tests, TypeScript 7 typecheck, TypeScript 6 comparison typecheck, and docs validation.

A packaged-consumer smoke test found an additional owner requirement:

  • a consumer with only typescript@7.0.2 still makes the published ankhorage-eslint wrapper load TypeScript 7 and crash;
  • adding TypeScript 6 only as a dependency of @ankhorage/devtools does not reliably isolate typed linting because package-manager hoisting can place typescript-eslint beside the consumer's TypeScript 7;
  • the consumer itself must receive the documented dual aliases. With those aliases, the same packaged wrapper executes typed lint rules normally while tsc remains TypeScript 7.

Sources:

MUST

  • Supersede/close chore: defer TypeScript 7 until ESLint support #94; do not merge a direct replacement of the canonical typescript package with TypeScript 7.
  • Define one canonical Devtools-owned TypeScript transition policy with two explicit lanes:
    • @typescript/native aliases stable typescript@7 and owns the tsc binary used by build/typecheck;
    • typescript aliases stable @typescript/typescript6 and owns the current JavaScript API used by typescript-eslint and other programmatic consumers.
  • Apply the dual aliases to Devtools itself and regenerate bun.lock with the repository-pinned Bun 1.4.0. A frozen install must reproduce tsc -> 7.x, tsc6 -> 6.x, and require('typescript') -> 6.x.
  • Make the package synchronization contract write the same two canonical dev dependencies into ordinary managed consumers. It must replace direct typescript@7, remove obsolete @typescript/native-preview declarations, preserve unrelated manifest fields, and remain byte-stable on a second sync.
  • Keep normal build and typecheck entrypoints on tsc so they use the native compiler. Do not rename the production compiler command to a repository-specific alias or keep two competing build paths.
  • Make the TypeScript 6 compatibility lane explicit in tests and documentation as a current TypeScript 7.0 ecosystem requirement, not as a legacy fallback. Record the removal gate: TypeScript must publish the new stable API and typescript-eslint must support it before the TS6 lane is removed.
  • Update the managed VS Code contract so repositories actually use the TypeScript 7 language server: recommend TypeScriptTeam.native-preview, enable js/ts.experimental.useTsgo, and point js/ts.tsdk.path at the native package alias. Keep the documented ability to disable the TS7 language server when a current tool requires TypeScript 6.
  • Add regression coverage for:
    • package metadata and both alias ranges;
    • binary/API version selection (tsc, tsc6, and require('typescript'));
    • migration of a direct TypeScript dependency through package sync;
    • idempotent package and lockfile synchronization;
    • a packed consumer fixture proving ankhorage-eslint performs typed linting while the consumer's tsc is TypeScript 7;
    • managed VS Code assets.
  • Verify Renovate tracks the two aliased packages independently and cannot recreate chore: defer TypeScript 7 until ESLint support #94's invalid direct-major update. Add configuration tests for the alias behavior rather than relying on a manual ignore.
  • Validate Devtools under both compilers during the migration: TypeScript 7 is the primary build/typecheck; TypeScript 6 must also compile with stableTypeOrdering enabled and without ignoreDeprecations, matching Microsoft's transition precondition.
  • Run the complete Devtools validation contract, add the required package changeset, release the owner package, and propagate the released policy through the existing Automate Devtools toolchain updates and downstream sync #64 automation rather than patching consumers manually.

SHOULD

  • Record before/after build and typecheck timings so the native compiler adoption has measurable acceptance evidence.
  • Audit managed repositories for TypeScript 7 CLI differences, especially scripts that pass source files to tsc while a tsconfig.json exists, and for tools/frameworks that embed the compiler API. Fix the owning package or keep those API calls on the canonical TS6 lane; do not add repository-local shims.
  • Add or update Doctor enforcement so a managed repository reports drift when tsc resolves to TypeScript 6, the typescript API resolves to TypeScript 7, or only one half of the current dual policy is installed.
  • Prove released end-to-end propagation in at least one normal package consumer and Studio, including frozen install, build, typed lint, tests, and typecheck.
  • Track typescript-eslint#10940 and TypeScript 7.1. Once the new API is stable and supported, open a focused cleanup issue to remove the TS6 lane, its editor fallback, and transition-only assertions in one canonical change.

Acceptance

  • Devtools CI is green with TypeScript 7 executing tsc and TypeScript 6 satisfying typed ESLint/API consumers.
  • A released, synchronized consumer has the same binary/API split and its published Devtools lint wrapper runs without the chore: defer TypeScript 7 until ESLint support #94 crash.
  • Managed editor settings select the TypeScript 7 language server.
  • Renovate updates the native and API lanes without collapsing them into an unsupported single TypeScript 7 dependency.
  • The release and downstream synchronization follow existing Devtools ownership; no consumer-specific compatibility implementation or manual repository-by-repository migration is introduced.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions