# Building a type from other types

Most object types in a real application are slices of an entity or of another
object: a create input, a patch input where every field is optional, a public
view, a list summary, a v2 response that adds a field. Instead of writing
each field out (`title: Todo.title`), a type's body can copy fields from
other types. The body keeps its ordinary `Output { }` form. Four kinds of
line build it. They are **read from top to bottom**, and each changes the
result of the lines above it:

| Line | Does |
|---|---|
| `include: [Todo]` | adds every field of each listed type (types only; never on an `Input`) |
| `pick: [Todo.id, Todo.title]` | adds just the listed fields, each keeping its own name |
| `omit: [Todo.internal_note]` | removes fields present at that point |
| `bar: User.bar` | a written field: replaces a field of the same name above, or adds a new one |

```jadpo
type TodoView = Output {
    pick: [Todo.id, Todo.title, Todo.status, Todo.due_at]
}

type TodoDetail = Output {
    include: [Todo]
    omit: [Todo.deleted_at]
    owner_email: User.email
}

type PatchTodo = Input {
    pick: [Todo.title, Todo.due_at]
    optional: all
}

type OrderView = Output {
    include: [Order]
    lines: List<OrderLineView>  // replaces Order.lines with a view of each line
}

type TodoReminder = Object {
    pick: [Todo.id, Todo.title, Todo.due_at]
    owner_email: User.email
    days_overdue: DayCount
}
```

Rules:

- **Top to bottom.** The same kind of line may appear more than once, and the
  formatter keeps the order written, because order matters here.
- **Fields keep their declared order.** Copied fields stand where their
  `include` or `pick` line is, an `include`'s in the order its type
  declares them and a `pick`'s in the order listed; a written field that
  replaces a copied one takes its place. Values, hover and the manifest
  (each field's `order`) follow it.
- **Lists are always in brackets**, even with one entry: `include: [Todo]`.
- **`omit` removes only what is there.** Omitting a field that is not present
  at that point is an error, which catches typos and fields since removed.
- **Written fields win.** A field you write replaces any field of the same
  name above it, visibly; otherwise it is added.
- **Copied fields never silently replace copied fields.** An `include` or
  `pick` that would replace a field brought in by an earlier `include` or
  `pick` is an error: resolve it with `omit` or by writing the field. Copied
  fields are not visible in the declaration, so a clash there would change a
  type unseen when a source type gains a field.
- **No `include` on an `Input`.** Taking every field of `User` would accept
  any field added to `User` later, so a client could set a field it was
  never meant to (the mass-assignment bug). Inputs `pick` or write their
  fields. Generated fields such as `id` and `created_at` can never
  appear in an `Input`.
- **`optional`** makes the listed fields, or `all`, optional, only on an
  `Input`.
- **Copied fields follow their source.** Renaming `Todo.title` renames it in
  every type that copies it, and its validation rules come with it.
- **No type includes itself.** An `include` that leads back to its own type,
  directly or through another, is `type.copy_cycle`.
- **Every built type has a name;** there are no inline types in signatures.
  Hover in your editor shows the final fields and where each came from
  (`title ← Todo.title`, `lines ← written, replaces Order.lines`).
- **Outputs may `include`.** A field added to `Todo` later reaches
  `TodoDetail`, and the committed API record shows the addition in review
  ([HTTP](http.md)). Fields that policy hides from clients stay hidden
  when the app runs ([Field restrictions](field-restrictions.md)).
- `include`, `pick`, `omit` and `optional` are reserved and cannot be field
  names.
