You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The TypeScript team published their TS 7.1 API roadmap in microsoft/TypeScript#63875.
Every item in it targets the JS-facing IPC/snapshot API (createProgram(options), transpileModule, parseCommandLine/readConfigFile, custom transformers, NodeHandle<T>, LSP middleware). None of it changes anything for a Go consumer:
the Go functions behind those APIs already exist, they just live in internal/.
The relevant part is in the comments. arthurfiorette asked about a direct Go
compiler API, and jakebailey replied:
When we move repos, we should be doing that, yeah, though perhaps not
instantly (we need to settle the major version situation)
That carries two things worth tracking here: a public Go API is intended (which
would let us delete shim/ and become go install-able), and the module path
is likely to change (repo move and/or a major-version bump), which breaks our
bump tooling and the shim module-path trick together.
Nothing is actionable upstream yet. This issue records the inventory and the
plan so we can move quickly when it is.
What we depend on today
Ten shimmed packages (~4,300 generated lines), but the generator shims whole
packages — the surface we actually consume is small:
All of that is exported upstream — it is only unreachable because of the internal/ boundary. Our genuinely-private dependency is five call sites:
Shim symbol
Uses
Public equivalent upstream?
checker.Checker_getAwaitedType
2
none
checker.Checker_getFullyQualifiedName
2
none
checker.Checker_getTypeArguments
1
yes — (*Checker).GetTypeArguments
checker.Checker_isTypeAssignableTo
2
yes — (*Checker).IsTypeAssignableTo
checker.Type_symbol
2
yes — (*Type).Symbol()
shim/checker/extra-shim.json additionally declares 24 checker methods and four
struct field mirrors (Type, TupleType, Signature, InterfaceType) that
nothing in the repo uses. The field mirrors are our only unsafe.Pointer layout
casts; tools/gen_shims regenerates them from upstream's real struct on every
bump, so they are correct, but they are dead weight.
Bottom line: if internal/checker et al. became importable tomorrow, we would
need exactly two things added to the public surface — getAwaitedType and getFullyQualifiedName. Worth raising upstream while the API is being
designed.
Preparation we can do now
Replace the three avoidable private accesses with their public
equivalents (c.GetTypeArguments, c.IsTypeAssignableTo, t.Symbol()),
then trim the unused ExtraMethods/ExtraFields from shim/checker/extra-shim.json. Removes every unsafe cast from the
generated shim and reduces our private surface to two symbols.
Parameterize the typescript-go module path and repo URL in tools/bump-tsgo.sh (currently hardcoded in the git ls-remote URL, the go list -m query, and the go mod edit -require) and in tools/gen_shims/main.go (tsgoInternalPrefix).
The good case — upstream makes the compiler packages importable at github.com/microsoft/typescript-go/<pkg> (or re-exports them from a public api/). Then:
Rewrite the 118 imports across 71 files: .../shim/X → the new public path.
Delete shim/ (10 modules) and the 10 replace + require pairs in the
root go.mod; add one direct require on typescript-go.
Delete tools/gen_shims and simplify tools/bump-tsgo.sh to a plain go get; the weekly workflow keeps working unchanged.
Replace the two remaining private calls with whatever public API upstream
provides (or keep a single minimal shim module just for those).
Drop the "not go install-able" caveats in README.md and AGENTS.md; the replace directives are what block installation from the proxy today.
Full fixture oracle (go test ./...) is the acceptance gate, as with any bump.
The bad case — upstream ships a narrow curated Go API modeled on the JS one
(program snapshots, node handles, no direct checker access). That will not cover TypeToTypeNode with a node builder, awaited/contextual types, type and object
flags, or bundled.LibPath. Evaluate the shape against the inventory above
before assuming migration is possible; if it does not cover us, the shims stay
and we file a gap report upstream.
Risk: module path change (repo move or major version)
jakebailey's "when we move repos" plus "the major version situation" both point
at the same breakage for us: the module path github.com/microsoft/typescript-go
changing (to a new repo path, or gaining a /v2 suffix).
What breaks:
Nothing at build time, immediately. The module proxy serves the pinned
pseudo-version immutably, so existing builds keep resolving even if the repo
is archived. No emergency.
tools/bump-tsgo.sh fails.go list -m github.com/microsoft/typescript-go@<ref>
hard-fails once the new location's go.mod declares a different path
("module declares its path as X but was required as Y"). The git ls-remote
against the old URL may keep working via GitHub's rename redirect, which makes
the failure look confusing — it will be the go list step.
The shim module-path trick needs a coordinated rename. Our shim modules are
named github.com/microsoft/typescript-go/shim/...specifically so that
importing github.com/microsoft/typescript-go/internal/... satisfies Go's
internal-package rule. If the upstream path changes, all 10 shim module
lines, the 10 root replace/require pairs, tsgoInternalPrefix in gen_shims, and all 118 import lines must move to the new prefix together, or
the internal imports stop being legal.
Mitigation is deliberately minimal: parameterize the path in the two tools (see
above) so the change is a two-file edit plus one sed over the imports. We
should not build an internal re-export layer to insulate the import sites —
that is a lot of indirection to save a mechanical rename, and it would hide
which upstream symbols we actually touch.
Watch signals
The weekly bump-typescript-go job failing is the primary canary and it
is already wired: tools/bump-tsgo.sh exits non-zero with "could not resolve
a typescript/v* release tag" if upstream stops publishing tags at the current
location, and the go list -m step fails on a declared-path mismatch. A red
scheduled run means "go read the upstream repo", not "flaky CI".
A go.modmodule line change, or a /v2+ tag, in microsoft/typescript-go.
Any archive/redirect notice on the typescript-go repo, or TS 7 Go sources
appearing under microsoft/TypeScript.
New top-level (non-internal/) Go packages upstream, an api/ package with
Go doc comments, or new exported wrappers appearing in internal/checker/exports.go.
Background
The TypeScript team published their TS 7.1 API roadmap in
microsoft/TypeScript#63875.
Every item in it targets the JS-facing IPC/snapshot API (
createProgram(options),transpileModule,parseCommandLine/readConfigFile, custom transformers,NodeHandle<T>, LSP middleware). None of it changes anything for a Go consumer:the Go functions behind those APIs already exist, they just live in
internal/.The relevant part is in the comments. arthurfiorette asked about a direct Go
compiler API, and jakebailey
replied:
That carries two things worth tracking here: a public Go API is intended (which
would let us delete
shim/and becomego install-able), and the module pathis likely to change (repo move and/or a major-version bump), which breaks our
bump tooling and the shim module-path trick together.
Nothing is actionable upstream yet. This issue records the inventory and the
plan so we can move quickly when it is.
What we depend on today
Ten shimmed packages (~4,300 generated lines), but the generator shims whole
packages — the surface we actually consume is small:
astNode,SourceFile,Symbol,Diagnostic,IdentifierNode,NodeList,Kind+ ~80Kind*constants,NodeFlagsConst/NodeFlagsJSDoc,SymbolFlagsAlias/SymbolFlagsTypeParameter,GetSourceFileOfNode,GetCombinedNodeFlags,GetNextJSDocCommentLocation, ~24Is*predicates, plus node methods (Symbol(),JSDoc(),TagName(),Text())checkerChecker,Type,TypeToTypeNode,GetTypeAtLocation,ObjectFlagsReference,TypeFlags{StringLiteral,NumberLiteral,Object,UnionOrIntersection,UniqueESSymbol}; methodsGetAliasedSymbol,GetConstantValue,GetExportsOfModule,GetExportSpecifierLocalTargetSymbol,GetPropertyOfType,GetSymbolAtLocation,GetTypeAtLocation,TypeToTypeNodecompilerProgram,ProgramOptions,CompilerHost,NewProgram,NewCompilerHost; methodsBindSourceFiles,GetSyntacticDiagnostics,GetSemanticDiagnostics,GetTypeCheckertsoptionsParsedCommandLine,NewParsedCommandLine,GetParsedCommandLineOfConfigFilecoreCompilerOptions,ScriptTargetES2022,ModuleKindCommonJS,TSTrue/TSFalse/TSUnknowntspathNormalizePath,ResolvePath,ComparePathsOptionsscannerGetTextOfNode,GetTextOfJSDocComment,GetSourceTextOfNodeFromSourceFilejsnumNumber,FromStringbundledLibPath,WrapFS(embeddedlib.*.d.ts)vfs/osvfsFSAll of that is exported upstream — it is only unreachable because of the
internal/boundary. Our genuinely-private dependency is five call sites:checker.Checker_getAwaitedTypechecker.Checker_getFullyQualifiedNamechecker.Checker_getTypeArguments(*Checker).GetTypeArgumentschecker.Checker_isTypeAssignableTo(*Checker).IsTypeAssignableTochecker.Type_symbol(*Type).Symbol()shim/checker/extra-shim.jsonadditionally declares 24 checker methods and fourstruct field mirrors (
Type,TupleType,Signature,InterfaceType) thatnothing in the repo uses. The field mirrors are our only
unsafe.Pointerlayoutcasts;
tools/gen_shimsregenerates them from upstream's real struct on everybump, so they are correct, but they are dead weight.
Bottom line: if
internal/checkeret al. became importable tomorrow, we wouldneed exactly two things added to the public surface —
getAwaitedTypeandgetFullyQualifiedName. Worth raising upstream while the API is beingdesigned.
Preparation we can do now
equivalents (
c.GetTypeArguments,c.IsTypeAssignableTo,t.Symbol()),then trim the unused
ExtraMethods/ExtraFieldsfromshim/checker/extra-shim.json. Removes everyunsafecast from thegenerated shim and reduces our private surface to two symbols.
tools/bump-tsgo.sh(currently hardcoded in thegit ls-remoteURL, thego list -mquery, and thego mod edit -require) and intools/gen_shims/main.go(tsgoInternalPrefix).getAwaitedTypeandgetFullyQualifiedNameon*Checker.Migration, if packages move out of
internal/The good case — upstream makes the compiler packages importable at
github.com/microsoft/typescript-go/<pkg>(or re-exports them from a publicapi/). Then:.../shim/X→ the new public path.shim/(10 modules) and the 10replace+requirepairs in theroot
go.mod; add one directrequireon typescript-go.tools/gen_shimsand simplifytools/bump-tsgo.shto a plaingo get; the weekly workflow keeps working unchanged.provides (or keep a single minimal shim module just for those).
go install-able" caveats inREADME.mdandAGENTS.md; thereplacedirectives are what block installation from the proxy today.go test ./...) is the acceptance gate, as with any bump.The bad case — upstream ships a narrow curated Go API modeled on the JS one
(program snapshots, node handles, no direct checker access). That will not cover
TypeToTypeNodewith a node builder, awaited/contextual types, type and objectflags, or
bundled.LibPath. Evaluate the shape against the inventory abovebefore assuming migration is possible; if it does not cover us, the shims stay
and we file a gap report upstream.
Risk: module path change (repo move or major version)
jakebailey's "when we move repos" plus "the major version situation" both point
at the same breakage for us: the module path
github.com/microsoft/typescript-gochanging (to a new repo path, or gaining a
/v2suffix).What breaks:
pseudo-version immutably, so existing builds keep resolving even if the repo
is archived. No emergency.
tools/bump-tsgo.shfails.go list -m github.com/microsoft/typescript-go@<ref>hard-fails once the new location's
go.moddeclares a different path("module declares its path as X but was required as Y"). The
git ls-remoteagainst the old URL may keep working via GitHub's rename redirect, which makes
the failure look confusing — it will be the
go liststep.named
github.com/microsoft/typescript-go/shim/...specifically so thatimporting
github.com/microsoft/typescript-go/internal/...satisfies Go'sinternal-package rule. If the upstream path changes, all 10 shim
modulelines, the 10 root
replace/requirepairs,tsgoInternalPrefixingen_shims, and all 118 import lines must move to the new prefix together, orthe internal imports stop being legal.
Mitigation is deliberately minimal: parameterize the path in the two tools (see
above) so the change is a two-file edit plus one
sedover the imports. Weshould not build an internal re-export layer to insulate the import sites —
that is a lot of indirection to save a mechanical rename, and it would hide
which upstream symbols we actually touch.
Watch signals
bump-typescript-gojob failing is the primary canary and itis already wired:
tools/bump-tsgo.shexits non-zero with "could not resolvea typescript/v* release tag" if upstream stops publishing tags at the current
location, and the
go list -mstep fails on a declared-path mismatch. A redscheduled run means "go read the upstream repo", not "flaky CI".
go.modmoduleline change, or a/v2+ tag, in microsoft/typescript-go.appearing under microsoft/TypeScript.
internal/) Go packages upstream, anapi/package withGo doc comments, or new exported wrappers appearing in
internal/checker/exports.go.a dedicated "public Go API" issue.
🤖 Analysis and issue drafted by Claude Code from
microsoft/TypeScript#63875.