nenu-lang / named-types-and-shapes
Stable

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

code
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

code
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

code
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

code
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

code
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

MistakeCorrection
Assume field order changes a shapeCompare names, types, and optional markers.
Treat two equal-shaped entities as interchangeableEntities remain nominal.
Write an empty or optional shape containerPut optional markers on fields instead.
Omit a field from a structurally compatible valueMatch the complete required field set.

Continue Learning