Skip to content

[API] CompilerOptions references enums that aren't exported, and omits options tsc acceptsΒ #64067

Description

πŸ”Ž Search Terms

CompilerOptions, JsxEmit, ModuleResolutionKind, esModuleInterop, API, unstable/sync

πŸ•— Version & Regression Information

  • This changed between versions 6.0 and 7.0 β€” TypeScript 6's public API exported the option enums and declared every compiler option.
  • Verified on 7.0.2 and on typescript@next (7.1.0-dev.20260827.1); both behave the same.

Related: #63910 (TypeFormatFlags enum missing) is the same class of problem and has been fixed β€” TypeFormatFlags is now reachable, while the two enums below are not.

πŸ’» Code

The API's CompilerOptions names two enums that no export path provides:

// dist/api/proto.generated.d.ts (7.1-dev); dist/api/compilerOptions.d.ts (7.0.2)
jsx?: JsxEmit;
moduleResolution?: ModuleResolutionKind;

Neither is exported from any of the package's twelve export paths:

for (const p of ["unstable/sync", "unstable/async", "unstable/fs", "unstable/proto",
                 "unstable/ast", "unstable/ast/is", "unstable/ast/factory",
                 "unstable/ast/utils", "unstable/ast/scanner", "unstable/ast/visitor",
                 "unstable/ast/clone"]) {
    const m = await import(`typescript/${p}`);
    for (const k of ["JsxEmit", "ModuleResolutionKind", "TypeFormatFlags"]) {
        if (m[k] !== undefined) console.log(p, k);
    }
}
// prints only: unstable/sync TypeFormatFlags

They exist in the package, but only under the internal #enums/* subpath:

node_modules/typescript/dist/enums/jsxEmit.enum.js
node_modules/typescript/dist/enums/moduleResolutionKind.enum.js

Separately, two options tsc accepts do not appear in CompilerOptions at all:

// tsconfig.json β€” tsc 7.0.2 accepts this and exits 0
{ "compilerOptions": { "esModuleInterop": true, "allowSyntheticDefaultImports": true, "noEmit": true } }
$ grep -rc "esModuleInterop" node_modules/typescript/dist/
0

πŸ™ Actual behavior

A typed CompilerOptions cannot be written:

  • jsx and moduleResolution can only be set by importing enums that are unreachable, so the field is unusable except via as any or a hand-copied numeric literal.
  • esModuleInterop and allowSyntheticDefaultImports are rejected as unknown properties, though the compiler honours them.

πŸ™‚ Expected behavior

Every enum a public type references is exported from a public path, and CompilerOptions covers the options the compiler accepts β€” so an API consumer can build one without casts.

Additional information about the issue

Found while porting a lossless-syntax tool (OpenRewrite's JavaScript/TypeScript parser) from the TypeScript 6 API to 7. The workaround is to bypass the type entirely and write the options as tsconfig JSON with string values ("jsx": "preserve", "moduleResolution": "bundler"), which does work β€” the gap is only in the typed surface.

I have filed the two together because they look like one cause: CompilerOptions being generated from, or hand-mirrored against, an incomplete source. Happy to split them if that is not the case.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions