Skip to content

fix: support TypeScript 7 and Bun for locale file transpilation - #795

Open
shadoworion wants to merge 2 commits into
codingcommons:mainfrom
shadoworion:feat/typescript-7-and-bun-support
Open

fix: support TypeScript 7 and Bun for locale file transpilation#795
shadoworion wants to merge 2 commits into
codingcommons:mainfrom
shadoworion:feat/typescript-7-and-bun-support

Conversation

@shadoworion

Copy link
Copy Markdown

Problem

TypeScript 7 (the Go-based compiler, stable since typescript@7.0.x) no longer ships the JavaScript compiler API: ts.createProgram does not exist and the package's main entry only exposes version information. This breaks the generator with ts.createProgram is not a function.

Fixes #794

Solution

The generator now resolves a transpilation strategy for locale files at runtime:

  1. Bun (process.versions.bun): locale files are bundled with the native Bun.build API — no typescript installation needed at all
  2. TypeScript ≤ 6: the existing ts.createProgram path, unchanged, but behind a lazy import with feature detection (typeof ts.createProgram === 'function')
  3. TypeScript 7: the installed package's tsc CLI is spawned (process.execPath + bin/tsc, no shell) with the same compiler flags; tsc emits even when it reports type errors (guaranteed because of --noLib), so the exit code is ignored and success is determined by the emitted files
  4. Otherwise: a clear error message with instructions

The TypeScript version used for feature-gating the generated syntax (satisfies, template literal types, …) is detected lazily as well: versionMajorMinortypescript/package.json version → a modern default. A missing or API-less typescript package therefore no longer crashes the CLI, importer or exporter at module-import time. typescript is now an optional peer dependency for Bun-only setups.

Also fixes a pre-existing bug: a missing await on containsFolders() in detectLocationOfCompiledBaseTranslation made its early-return dead code.

Verification

  • TypeScript 5 regression (Node): full workspace test suite (412 tests) + tsc --noEmit + eslint pass; e2e run against a sample project (dictionary with JSON import) produces output identical to the published package
  • TypeScript 7.0.2: version detected as 7.0.x, dictionary parsed via the spawned tsc CLI (all flags accepted by the native compiler), correct types generated
  • No typescript installed (Node): graceful info log (assuming version >= 5.5) and an actionable error message
  • Bun 1.3.14: generation works without typescript installed, watch mode regenerates types on dictionary changes, both TypeScript and JavaScript (module.exports) output formats work, JSON imports are bundled natively

🤖 Generated with Claude Code

TypeScript 7 (the Go-based compiler) no longer ships the JavaScript
compiler API: 'ts.createProgram' does not exist and the package's main
entry only exposes version information. The generator now resolves a
transpilation strategy at runtime:

1. Bun: locale files are bundled with the native 'Bun.build' API —
   no 'typescript' installation needed at all
2. TypeScript <= 6: the existing 'ts.createProgram' path, now behind a
   lazy import with feature detection
3. TypeScript 7: the installed package's 'tsc' CLI is spawned with the
   same compiler flags (emit still happens despite '--noLib' type
   errors, so the exit code is ignored)

The TypeScript version used for feature-gating the generated syntax is
detected lazily as well ('versionMajorMinor', then the package.json
version, then a modern default), so a missing or API-less 'typescript'
package no longer crashes the CLI, importer or exporter at import time.
'typescript' is now an optional peer dependency for Bun-only setups.

Also fixes a missing 'await' in 'detectLocationOfCompiledBaseTranslation'
that made its early-return dead code.

Ref: codingcommons#794

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

@Sayrix Sayrix left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tested the Node fallback from this PR with TypeScript 7.0.2 in a project that has a tsconfig.json, and it still fails with:

error TS5112: tsconfig.json is present but will not be loaded if files are
specified on commandline. Use '--ignoreConfig' to skip this error.

The command exits with code 1 and emits no files. Adding --ignoreConfig to the tsc arguments fixes it and emits the expected JavaScript.

process.execPath,
[
tscPath,
languageFilePath,

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This also needs --ignoreConfig. With TypeScript 7.0.2, passing a source file while the project contains a tsconfig.json produces TS5112 and emits nothing. I confirmed that adding the flag makes the same command emit the expected files.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch, thank you! Reproduced it — with a tsconfig.json present, tsc 7.0.2 aborts with TS5112 and emits nothing, so the fallback reported "No usable TypeScript compiler was found".

Fixed in 6f65ac0 by adding --ignoreConfig to the spawned arguments. The flag is passed unconditionally because this code path is only reachable on TypeScript >= 7 (older versions still provide the compiler API and take the programmatic ts.createProgram branch, which never read the user's tsconfig.json either — so behavior stays consistent).

Verified with TypeScript 7.0.2 + tsconfig.json (previously failing, now generates correctly) and re-ran the TypeScript 5 and Bun scenarios as regression.

TypeScript 7 aborts with 'error TS5112' (and emits nothing) when files
are passed on the command line while a 'tsconfig.json' exists in the
project — a situation that is the norm rather than the exception.
Classic 'tsc' silently ignored the config file in this case; the new
'--ignoreConfig' flag restores that behavior.

The flag only exists in TypeScript >= 7, which is safe because this
code path is only reachable when the compiler API is missing — older
versions always take the programmatic 'ts.createProgram' branch.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
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.

[BUG]: Typescript 7+ support

2 participants