Skip to content

TypeScript Code Generation

The browser generator produces a single TypeScript file with all types, formatters, and client classes.

Output

Unlike the C# multi-file approach, TypeScript generates a single file:

MyProject.Generated/

└── MyProject.ts — all types, formatters, and clients

Generate with:

ionc compile --only browser

Type Generation

Messages → Interfaces

// From: msg User { id: u4; name: string; email: string?; }

export interface User {
    id: number;
    name: string;
    email: string | null;
}

Enums → String Enums

// From: enum Status: u1 { Active, Inactive }

export enum Status {
    Active = 0,
    Inactive = 1
}

Unions → Discriminated Unions

// From: union Shape { Circle(r: f4), Rectangle(w: f4, h: f4) }

export type Shape =
    | { _tag: "Circle"; r: number }
    | { _tag: "Rectangle"; w: number; h: number };

Typedefs → Type Aliases

// From: typedef UserId = u4;

export type UserId = number;

Type Mapping

Ion Type TypeScript Type
i1, i2, i4, u1, u2, u4, f2, f4, f8 number
i8, i16, u8, u16, bigint bigint
bool boolean
string, uri string
bytes Uint8Array
guid string
datetime, dateonly, timeonly Date
duration number
T? T | null
T[] T[]

Generated Clients

Each service generates a client class that uses ion.webcore.js for transport:

// Generated from: service UserService(spaceId: u4) { GetUser(userId: u4): User; }

export class UserServiceClient {
    constructor(baseUrl: string, spaceId: number, options?: ClientOptions);

    async GetUser(userId: number): Promise<User>;
}

Formatters

Generated formatters are registered with IonFormatterStorage and handle CBOR array serialization:

// Auto-registered at module load
IonFormatterStorage.register("User", {
    serialize(writer: IonBinaryWriter, value: User) {
        writer.writeArrayHeader(3);
        writer.writeUInt32(value.id);
        writer.writeString(value.name);
        if (value.email !== null) writer.writeString(value.email);
        else writer.writeNull();
    },
    deserialize(reader: IonBinaryReader): User {
        reader.readArrayHeader();
        return {
            id: reader.readUInt32(),
            name: reader.readString(),
            email: reader.isNull() ? null : reader.readString()
        };
    }
});

Usage Example

import { UserServiceClient } from './MyProject';

const client = new UserServiceClient("https://api.example.com", 1);

// Fully typed — TypeScript knows this returns User
const user = await client.GetUser(42);
console.log(user.name);       // string
console.log(user.email);      // string | null