TypeScript Target Overview
Genotype generates idiomatic TypeScript code that can be used directly in the application or published as a package.
This overview shows how Genotype types translate to TypeScript, target-specific features and configuration options.
See the Quick Genotype Language Tour for the language overview and TypeScript Configuration for detailed configuration reference.
Translation
Section titled “Translation”The following examples give an overview of how Genotype translates into TypeScript.
Complete Module
Section titled “Complete Module”This source combines an object, a literal field, an optional field, a record, and any:
Book: { kind: "book", displayTitle: string, subtitle?: string, ratings: { []: int }, extra: any,}The generated module includes its definitions and any required imports:
export interface Book { kind: "book"; displayTitle: string; subtitle?: string | undefined; ratings: Record<string, number>; extra: any;}export type Book = { kind: "book"; displayTitle: string; subtitle?: string | undefined; ratings: Record<string, number>; extra: any;};import { z } from "zod";
export const Book = z.object({ kind: z.literal("book"), displayTitle: z.string(), subtitle: z.union([z.string(), z.undefined()]).optional(), ratings: z.record(z.string(), z.number()), extra: z.any()});
export type Book = z.infer<typeof Book>;Unions
Section titled “Unions”Genotype unions translate directly to TypeScript union types.
Value: string | intexport type Value = string | number;export const Value = z.union([z.string(), z.number()]);
export type Value = z.infer<typeof Value>;Primitives
Section titled “Primitives”Numeric Types
Section titled “Numeric Types”number
Section titled “number”Genotype number translates directly to the TypeScript number type.
Amount: numberexport type Amount = number;export const Amount = z.number();
export type Amount = z.infer<typeof Amount>;Genotype int translates into the TypeScript umbrella number type.
Count: intexport type Count = number;export const Count = z.number();
export type Count = z.infer<typeof Count>;Genotype float translates into the TypeScript umbrella number type.
Ratio: floatexport type Ratio = number;export const Ratio = z.number();
export type Ratio = z.infer<typeof Ratio>;Sized Numeric Types
Section titled “Sized Numeric Types”Sized Genotype numeric types translate into the TypeScript umbrella number type, except for i128 and u128, which translate into bigint.
SmallCount: i16PreciseRatio: f32LargeCount: i128export type SmallCount = number;
export type PreciseRatio = number;
export type LargeCount = bigint;export const SmallCount = z.number();
export type SmallCount = z.infer<typeof SmallCount>;
export const PreciseRatio = z.number();
export type PreciseRatio = z.infer<typeof PreciseRatio>;
export const LargeCount = z.bigint();
export type LargeCount = z.infer<typeof LargeCount>;Booleans
Section titled “Booleans”Genotype boolean translates directly to the TypeScript boolean type.
Ready: booleanexport type Ready = boolean;export const Ready = z.boolean();
export type Ready = z.infer<typeof Ready>;Strings
Section titled “Strings”Genotype string translates directly to the TypeScript string type.
Title: stringexport type Title = string;export const Title = z.string();
export type Title = z.infer<typeof Title>;Literal Types
Section titled “Literal Types”Genotype literal types translate directly to TypeScript literal types.
Category: "fiction"export type Category = "fiction";export const Category = z.literal("fiction");
export type Category = z.infer<typeof Category>;Genotype null translates directly to the TypeScript null type.
Empty: nullexport type Empty = null;export const Empty = z.literal(null);
export type Empty = z.infer<typeof Empty>;Branded Primitives
Section titled “Branded Primitives”Genotype branded primitives translate into branded TypeScript types. Their runtime values remain unchanged.
BookId: @stringexport type BookId = string & { [bookIdBrand]: true };declare const bookIdBrand: unique symbol;export const BookId = z.string().brand<"BookId">();
export type BookId = z.infer<typeof BookId>;Composite Types
Section titled “Composite Types”Objects
Section titled “Objects”Genotype objects translate into TypeScript interfaces or type aliases. Choose the output style with ts.prefer.
Book: { title: string }export interface Book { title: string;}export type Book = { title: string;};export const Book = z.object({ title: z.string()});
export type Book = z.infer<typeof Book>;Optional Object Fields
Section titled “Optional Object Fields”Optional Genotype object fields translate into optional TypeScript properties.
Draft: { subtitle?: string }export interface Draft { subtitle?: string | undefined;}export type Draft = { subtitle?: string | undefined;};export const Draft = z.object({ subtitle: z.union([z.string(), z.undefined()]).optional()});
export type Draft = z.infer<typeof Draft>;Object Extensions
Section titled “Object Extensions”Genotype object extensions translate into interface inheritance or type intersections.
Named: { name: string }NamedBook: { ...Named, pages: int }export interface Named { name: string;}
export interface NamedBook extends Named { pages: number;}export type Named = { name: string;};
export type NamedBook = Named & { pages: number;};export const Named = z.object({ name: z.string()});
export type Named = z.infer<typeof Named>;
export const NamedBook = Named.extend({ pages: z.number()});
export type NamedBook = z.infer<typeof NamedBook>;Arrays
Section titled “Arrays”Genotype arrays translate into TypeScript Array<T> types.
Titles: [string]export type Titles = Array<string>;export const Titles = z.array(z.string());
export type Titles = z.infer<typeof Titles>;Tuples
Section titled “Tuples”Genotype tuples translate directly to TypeScript tuple types.
Point: (float, float)export type Point = [number, number];export const Point = z.tuple([z.number(), z.number()]);
export type Point = z.infer<typeof Point>;Records
Section titled “Records”Genotype records translate into TypeScript Record<K, V> types. An omitted key type means string keys.
Scores: { []: int }export type Scores = Record<string, number>;export const Scores = z.record(z.string(), z.number());
export type Scores = z.infer<typeof Scores>;Special Data Types
Section titled “Special Data Types”Any Type
Section titled “Any Type”Genotype any translates directly to the TypeScript any type.
Payload: anyexport type Payload = any;export const Payload = z.any();
export type Payload = z.infer<typeof Payload>;Generic Types
Section titled “Generic Types”Genotype generic types translate into TypeScript generic types. Zod output uses functions accepting schemas, e.g., Envelope(Book).
Envelope<Body>: { body: Body }export interface Envelope<Body> { body: Body;}export type Envelope<Body> = { body: Body;};export const Envelope = <Body extends z.ZodTypeAny>(Body: Body) => z.object({ body: Body});
export type Envelope<Body extends z.ZodTypeAny> = z.infer<ReturnType<typeof Envelope<Body>>>;Recursive Types
Section titled “Recursive Types”Genotype recursive types translate directly to TypeScript recursive types. Zod output uses getters or lazy schemas.
LinkedNode: { value: string, next?: LinkedNode }export interface LinkedNode { value: string; next?: LinkedNode | undefined;}export type LinkedNode = { value: string; next?: LinkedNode | undefined;};export const LinkedNode = z.object({ value: z.string(), get next() { return z.union([LinkedNode, z.undefined()]).optional() }});
export type LinkedNode = z.infer<typeof LinkedNode>;Annotations
Section titled “Annotations”Annotations intended for other targets, such as Rust enum variant names, don’t affect TypeScript output.
Configuration
Section titled “Configuration”Use [ts] in genotype.toml to configure TypeScript. See the TypeScript Configuration Reference for more details.
See Genotype Configuration for global settings and Common Target Options.