# Can typescript-go Generate Union Types from Go? A Technical Deep Dive

> Discover if typescript-go generates union types from Go. This article clarifies its function as a Go-based TypeScript compiler, not a Go to TypeScript transpiler.

- Repository: [Microsoft/typescript-go](https://github.com/microsoft/typescript-go)
- Tags: deep-dive
- Published: 2026-04-25

---

**No, typescript-go cannot generate TypeScript union types from Go source code because it is a TypeScript compiler implementation written in Go, not a source-to-source transpiler that converts Go into TypeScript.**

The **typescript-go** repository represents Microsoft's experimental effort to reimplement the TypeScript compiler in Go for improved performance. Despite being implemented in Go, this compiler exclusively parses TypeScript (`.ts` and `.tsx`) files and emits JavaScript or declaration files, meaning it possesses no capability to inspect Go structs or interfaces and generate corresponding TypeScript union types.

## Understanding the Compiler's Architecture

The typescript-go project serves as a complete reimplementation of the TypeScript language services. It performs lexical analysis, syntactic parsing, type checking, and code emission—functionally mirroring the original TypeScript compiler but with Go's runtime characteristics.

The compiler builds an Abstract Syntax Tree (AST) from TypeScript source code, where union types are represented internally as **UnionTypeNode** structures. These nodes are defined in [`internal/ast/ast_generated.go`](https://github.com/microsoft/typescript-go/blob/main/internal/ast/ast_generated.go) at lines 5299-5315, containing the constituent types joined by the `|` operator.

## How Union Types Are Processed Internally

When working with TypeScript source files, the compiler handles union types through three distinct phases: parsing, AST representation, and code emission.

### Parsing Union Syntax

When the parser encounters the `|` token within a type annotation, it invokes the `parseUnionOrIntersectionType` function in [`internal/parser/parser.go`](https://github.com/microsoft/typescript-go/blob/main/internal/parser/parser.go) (lines 2631-2665). This function constructs a **UnionTypeNode** by collecting individual type constituents and validating their positions within the type hierarchy.

### AST Representation and Validation

The internal structure resides in [`internal/ast/ast_generated.go`](https://github.com/microsoft/typescript-go/blob/main/internal/ast/ast_generated.go), where the `UnionTypeNode` struct stores references to constituent types. Helper predicates like `IsUnionTypeNode` enable the type checker and transformers to identify these nodes during tree traversal and semantic analysis.

### Code Emission and Printing

During the emission phase, [`internal/printer/printer.go`](https://github.com/microsoft/typescript-go/blob/main/internal/printer/printer.go) (lines 2010-2020) implements `emitUnionType` and `emitUnionTypeConstituent` to regenerate the `a | b` syntax. Additionally, the declaration transformer in [`internal/transformers/declarations/transform.go`](https://github.com/microsoft/typescript-go/blob/main/internal/transformers/declarations/transform.go) (lines 2006-2027) constructs **UnionTypeNode** instances when generating declaration files from existing TypeScript sources.

## Why Go Source Code Cannot Generate Union Types

Although typescript-go is implemented in Go, the codebase contains no components that parse Go files or translate Go constructs into TypeScript AST nodes. The CLI entry point at [`cmd/tsgo/main.go`](https://github.com/microsoft/typescript-go/blob/main/cmd/tsgo/main.go) explicitly restricts input to TypeScript extensions, and the parser immediately fails on Go syntax.

Consider this Go struct definition:

```go
// file: shapes.go
type Shape struct {
    Kind   string // "circle" or "square"
    Radius float64
    Side   float64
}

```

There is no function within the repository that walks Go AST nodes and produces a **UnionTypeNode**. The constructors for union types exclusively accept TypeScript AST nodes as parameters, confirming the compiler processes only TypeScript-to-JavaScript transformation, not Go-to-TypeScript transpilation.

## Working with Union Types in typescript-go

To utilize union types, you must author TypeScript code directly. The compiler fully supports union syntax written in TypeScript:

```typescript
// file: shapes.ts
type Shape = 
    | { kind: "circle"; radius: number }
    | { kind: "square"; side: number };

function area(s: Shape): number {
    if (s.kind === "circle") return Math.PI * s.radius ** 2;
    return s.side ** 2;
}

```

Compiling with the typescript-go CLI:

```bash
npx tsgo shapes.ts

```

The compiler parses the `|` tokens, creates the **UnionTypeNode** in its AST, performs type narrowing analysis, and emits the corresponding JavaScript. For decorator metadata, the compiler additionally handles union type serialization through `serializeUnionOrIntersectionConstituents` in [`internal/transformers/tstransforms/typeserializer.go`](https://github.com/microsoft/typescript-go/blob/main/internal/transformers/tstransforms/typeserializer.go).

## Summary

- **typescript-go** is a TypeScript compiler written in Go, not a transpiler from Go to TypeScript.
- The compiler constructs **UnionTypeNode** instances defined in [`internal/ast/ast_generated.go`](https://github.com/microsoft/typescript-go/blob/main/internal/ast/ast_generated.go) exclusively from TypeScript source input.
- Parsing occurs via `parseUnionOrIntersectionType` in [`internal/parser/parser.go`](https://github.com/microsoft/typescript-go/blob/main/internal/parser/parser.go), while emission uses `emitUnionType` in [`internal/printer/printer.go`](https://github.com/microsoft/typescript-go/blob/main/internal/printer/printer.go).
- The `tsgo` CLI only accepts `.ts` and `.tsx` files, rejecting Go source files entirely.
- Union types must be authored manually in TypeScript or generated by separate tooling, then fed to typescript-go for compilation.

## Frequently Asked Questions

### Is typescript-go a transpiler that converts Go code to TypeScript?

No. typescript-go is a TypeScript compiler implementation that parses TypeScript and emits JavaScript. While the compiler itself is written in Go, it does not understand Go syntax or transpile Go constructs into TypeScript definitions.

### What file extensions does typescript-go accept?

The compiler only processes files with `.ts` or `.tsx` extensions. According to the CLI implementation in [`cmd/tsgo/main.go`](https://github.com/microsoft/typescript-go/blob/main/cmd/tsgo/main.go), attempting to compile Go files or other languages results in parsing errors because the lexical analyzer only recognizes TypeScript grammar tokens.

### How are union types represented in the typescript-go AST?

Union types use the **UnionTypeNode** struct defined in [`internal/ast/ast_generated.go`](https://github.com/microsoft/typescript-go/blob/main/internal/ast/ast_generated.go) (lines 5299-5315). The parser instantiates these nodes via `parseUnionOrIntersectionType` in [`internal/parser/parser.go`](https://github.com/microsoft/typescript-go/blob/main/internal/parser/parser.go) when encountering the `|` operator, and the printer emits them through `emitUnionType` in [`internal/printer/printer.go`](https://github.com/microsoft/typescript-go/blob/main/internal/printer/printer.go).

### Can I automatically generate TypeScript union types from Go structs using this tool?

No. The repository contains no logic to inspect Go-specific constructs like structs or interfaces. To generate TypeScript definitions containing unions from Go code, you must use a separate code generation tool or write the TypeScript interfaces manually before compilation.