Named Types And Shapes
- A type definition names a reusable value shape; it does not create durable storage.
- Unnamed shapes are useful for local and response projections.
- Shape compatibility compares field names, types, and optional markers—not field order.
Defining A Named Value Type
1type BalanceRow {2 member: User3 paid: number4 owed: number5 balance: number6}This definition describes a reusable value. It does not create a table, durable identity, or storage API. Use an entity when the value must be stored as its own record.
Unnamed Structural Shapes
1{ label: string, amount: number } summary = {2 label: "Room total"3 amount: 2404}56rows = expenses.collect({7 label: it.title8 amount: it.amount9})An unnamed shape is ideal when a local projection is small and used once. Give the structure a named type when several functions, contracts, or pages share it.
Structural Compatibility
1type AmountLabel {2 label: string3 amount: number4}56AmountLabel row = { amount: 50, label: "Groceries" }- Field order is not semantic.
- Field names must match.
- Field types must match.
- Optional markers must match.
- Entities and enums remain nominal even when their fields look identical.
Nested And Collection Shapes
1type RoomSummary {2 room: { name: string }3 balances: { member: User, amount: number }[]4 note: string?5}Shapes may nest and may appear inside arrays. Empty shapes and optional shape containers are rejected. Put ? on individual scalar or named fields instead.
Transforms And Validators In Contracts
1type ExpenseInput {2 title: string | lowercase | trim3 receipt_email: string | lowercase | trim ! email4 amount: number5}A transform pipeline uses | and runs before a validator introduced by !. Use only transforms and validators supplied by the active contract; their names are not arbitrary functions.
Common Mistakes
| Mistake | Correction |
|---|---|
| Assume field order changes a shape | Compare names, types, and optional markers. |
| Treat two equal-shaped entities as interchangeable | Entities remain nominal. |
| Write an empty or optional shape container | Put optional markers on fields instead. |
| Omit a field from a structurally compatible value | Match the complete required field set. |
