Skip to content

Models and properties

Models are Typra’s primary unit of generation. A TypeSpec model becomes a target model surface; properties become target fields or properties.

model FixtureRoot {
name: string;
description?: string;
owner: FixtureOwner;
}
model FixtureOwner {
id: string;
displayName?: string;
}
TypeSpecTypra mapping
name: stringRequired scalar field.
description?: stringOptional scalar field.
owner: FixtureOwnerRequired nested object field.
displayName?: stringOptional nested object field.

Targets choose idiomatic syntax for the same shape: TypeScript emits classes and optional properties, Python emits model surfaces with loader/saver helpers, C# emits System.Text.Json-oriented types, Go emits structs with JSON/YAML helper behavior, and Swift emits TypraModel structs in a SwiftPM package.

These snippets are abridged from the generated fixture output so the same TypeSpec model can be compared across targets.

export class FixtureRoot {
name: string = "";
description?: string | undefined;
tags: string[] = [];
metadata?: Record<string, unknown> | undefined;
owner!: FixtureOwner;
static load(data: Record<string, unknown>, context?: LoadContext): FixtureRoot {
const instance = new FixtureRoot();
instance.name = String(data["name"]);
instance.owner = FixtureOwner.load(data["owner"] as Record<string, unknown>, context);
return instance;
}
save(context?: SaveContext): Record<string, unknown> {
return {
name: this.name,
...(this.description !== undefined ? { description: this.description } : {}),
tags: this.tags,
metadata: this.metadata,
owner: this.owner.save(context),
};
}
}

Typra’s @sample decorator supplies generated test and example data:

model FixtureOwner {
@sample(#{ id: "owner-1" })
id: string;
@sample(#{ displayName: "Fixture Owner" })
displayName?: string;
}

Samples are not runtime defaults. They are generation evidence for tests and examples.