TypeScript-Go Output Format: How the tsgo CLI Emits JavaScript and Declaration Files
The TypeScript-Go compiler (tsgo) produces JavaScript files (.js, .mjs, .cjs, or .jsx), optional source maps (.js.map), TypeScript declaration files (.d.ts), declaration maps (.d.ts.map), and incremental build info files (.tsbuildinfo) using the same emission logic as the official TypeScript compiler.
The microsoft/typescript-go repository implements a native Go port of the TypeScript compiler, exposing the tsgo CLI for drop-in compatibility with existing TypeScript workflows. Understanding the typescript-go output format helps developers configure build pipelines, as the tool replicates tsc behavior while delivering significantly faster compilation performance.
JavaScript File Emission and Extension Mapping
The core mechanism for determining output extensions resides in internal/outputpaths/outputpaths.go. The GetOutputExtension function examines the source file's extension and the --jsx compiler option to decide the resulting JavaScript file type.
func GetOutputExtension(fileName string, jsx core.JsxEmit) string {
switch {
case tspath.FileExtensionIs(fileName, tspath.ExtensionJson):
return tspath.ExtensionJson
case jsx == core.JsxEmitPreserve && tspath.FileExtensionIsOneOf(fileName, []string{tspath.ExtensionJsx, tspath.ExtensionTsx}):
return tspath.ExtensionJsx
case tspath.FileExtensionIsOneOf(fileName, []string{tspath.ExtensionMts, tspath.ExtensionMjs}):
return tspath.ExtensionMjs
case tspath.FileExtensionIsOneOf(fileName, []string{tspath.ExtensionCts, tspath.ExtensionCjs}):
return tspath.ExtensionCjs
default:
return tspath.ExtensionJs
}
}
Reference: internal/outputpaths/outputpaths.go#L9-L22
Extension Resolution Logic
The function applies the following rules when mapping source files to output extensions:
.tsor.tsx(standard): Emits.js.mtsor.mjs: Emits.mjs(ES modules).ctsor.cjs: Emits.cjs(CommonJS).tsxor.jsxwith--jsx preserve: Emits.jsx(JSX preserved).json: Passes through unchanged as.json
The computed extension feeds into getOwnEmitOutputFilePath, which prefixes the output directory (if configured) and constructs the final filesystem path.
Declaration Files and Source Maps
TypeScript-Go generates additional artifacts based on compiler options passed to the CLI.
Declaration File Emission
When declaration: true is set (or --emitDeclarationOnly is used), the compiler invokes GetDeclarationEmitOutputFilePath in internal/outputpaths/outputpaths.go to produce .d.ts files:
func GetDeclarationEmitOutputFilePath(file string, options *core.CompilerOptions, host OutputPathsHost) string {
// …determine output directory…
declarationExtension := tspath.GetDeclarationEmitExtensionForPath(path) // always ".d.ts"
return tspath.RemoveFileExtension(path) + declarationExtension
}
Reference: internal/outputpaths/outputpaths.go#L24-L41
Source Map Generation
Source maps are emitted when sourceMap: true and inlineSourceMap: false. The GetSourceMapFilePath function appends .map to the JavaScript output path:
func GetSourceMapFilePath(jsFilePath string, options *core.CompilerOptions) string {
if options.SourceMap.IsTrue() && !options.InlineSourceMap.IsTrue() {
return jsFilePath + ".map"
}
return ""
}
Reference: internal/outputpaths/outputpaths.go#L93-L99
Incremental Build Information
For incremental compilation or project-reference builds, TypeScript-Go generates a .tsbuildinfo file via GetBuildInfoFileName:
func GetBuildInfoFileName(options *core.CompilerOptions, opts tspath.ComparePathsOptions) string {
// …compute output location…
return buildInfoExtensionLess + tspath.ExtensionTsBuildInfo // ".tsbuildinfo"
}
Reference: internal/outputpaths/outputpaths.go#L200-L222
This file is created when incremental: true is enabled or when using --build mode, caching program state for faster subsequent compilations.
Command-Line Examples
Basic Compilation
Compile a single file to JavaScript without additional artifacts:
npx tsgo foo.ts
# Output: ./foo.js
Enable Source Maps
Generate separate .js.map files for debugging:
npx tsgo foo.ts --sourceMap
# Outputs: ./foo.js, ./foo.js.map
Emit Type Declarations
Produce .d.ts files alongside JavaScript:
npx tsgo foo.ts --declaration
# Outputs: ./foo.js, ./foo.d.ts
Preserve JSX Syntax
Maintain JSX syntax in the output for transformer processing:
npx tsgo component.tsx --jsx preserve
# Output: ./component.jsx
Module-Specific Output
Leverage ES module or CommonJS specific extensions:
# ES modules
npx tsgo lib.mts
# Output: lib.mjs
# CommonJS
npx tsgo lib.cts
# Output: lib.cjs
Incremental Build
Enable build caching for large projects:
npx tsgo project/tsconfig.json --incremental
# Outputs: compiled JS files, ./tsconfig.tsbuildinfo
Key Source Files
- CLI Entry Point:
cmd/tsgo/main.go(link) - Command Execution:
internal/execute/commandline.go(link) - Output Path Logic:
internal/outputpaths/outputpaths.go(link) - Path Utilities:
internal/tspath/extension.go(link)
Summary
- TypeScript-Go mirrors the official TypeScript compiler's output format, ensuring drop-in compatibility with existing toolchains.
- The
GetOutputExtensionfunction ininternal/outputpaths/outputpaths.godetermines whether to emit.js,.mjs,.cjs, or.jsxbased on source extensions and the--jsxflag. - Declaration files (
.d.ts) generate whendeclaration: true, while source maps (.js.map) requiresourceMap: trueandinlineSourceMap: false. - Build info files (
.tsbuildinfo) support incremental compilation when enabled via--incrementalor--buildflags. - Entry points
cmd/tsgo/main.goandinternal/execute/commandline.goorchestrate the emission process by invoking path calculation logic before writing files.
Frequently Asked Questions
What file extensions does TypeScript-Go generate?
TypeScript-Go emits .js for standard TypeScript files, .mjs for .mts sources, .cjs for .cts sources, and .jsx when compiling .tsx files with --jsx preserve. It optionally produces .d.ts declarations, .js.map source maps, and .tsbuildinfo incremental build files.
How do I enable source maps in tsgo?
Pass the --sourceMap flag on the command line. TypeScript-Go checks options.SourceMap.IsTrue() and ensures options.InlineSourceMap.IsTrue() is false to emit separate .js.map files alongside your JavaScript output, as implemented in GetSourceMapFilePath.
Does TypeScript-Go support incremental compilation?
Yes. When you specify --incremental or use --build mode for project references, TypeScript-Go calls GetBuildInfoFileName to generate a .tsbuildinfo file. This caches the program's state, allowing subsequent compilations to skip unchanged files and significantly improve build times.
How does tsgo output differ from the standard TypeScript compiler (tsc)?
There is no difference in output format. TypeScript-Go is designed as a native Go port that produces byte-identical JavaScript, declarations, and source maps compared to the official TypeScript compiler. The logic in internal/outputpaths/outputpaths.go replicates tsc behavior exactly, ensuring existing build configurations remain compatible.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →