# Generated TypeScript types > Generate deterministic TypeScript interfaces for your collections with myna types generate. `myna types generate` turns canonical collection schemas into a standalone TypeScript module: one interface per collection plus a `MynaCollections` registry. Generation is pure and deterministic — the same schemas always yield byte-identical output, and no user-written files are ever touched. ```bash $ myna types generate --out src/myna-types.ts ``` ## Options | Flag | Effect | |---|---| | `--schema-dir ` | Read schemas from a specific local directory (default `myna/`, resolved against the linked project root). | | `--deployed` | Generate from the deployed schemas (latest version per collection) instead of local files. | | `--out ` | Write to a file; without it, the module is printed to stdout. | By default types come from your local [schema files](/schema/defining-schemas), loaded with the same conventions as `myna schema diff`. Use `--deployed` to match exactly what the API serves, regardless of local edits. ## Output shape Collections are sorted by name. Each becomes an `export interface` named as the PascalCase of the collection key (`blog_posts` → `BlogPosts`), with a doc comment carrying the label and kind. Field `description`s become doc comments; optional fields (`required: false`) get `?`. The module starts with a header comment and a `JsonValue` type alias, and ends with the registry: ```ts export type JsonValue = string | number | boolean | null | JsonValue[] | { [key: string]: JsonValue }; /** Blog posts (collection) */ export interface Posts { title: string; slug: string; status?: "draft" | "review" | "live"; body: string; publishedAt?: string; cover?: string; author?: string; tags?: string[]; seo?: { metaTitle?: string; metaDescription?: string; }; } export interface MynaCollections { "posts": { fields: Posts; sortable: "title" | "slug" | "status" | "publishedAt"; reference: "author"; }; } ``` `MynaCollections` is the registry the SDK consumes. Alongside the field payload it records two things the field types alone cannot express: - **`sortable`** — the fields the query engine can order and filter by (scalars, excluding localized fields). A markdown `body` and a text `title` are both `string`, but only one of them can be sorted on, so the distinction has to be carried separately. - **`reference`** — the reference fields `include` can resolve. ## Using them Pass the registry to `createMyna` and the client stops returning `Record`: ```ts import { createMyna } from "@myna-sh/sdk"; import type { MynaCollections } from "./myna.generated"; const myna = createMyna({ project: "my-site" }); const posts = await myna.entries.list("posts", { order: "-publishedAt" }); posts.data[0].fields.title; // string — no cast ``` The compiler then rejects what the API would reject at runtime: ```ts await myna.entries.list("nope"); // unknown collection await myna.entries.list("posts", { order: "body" }); // markdown is not sortable await myna.entries.list("posts", { filter: { body: "x" } }); await myna.entries.list("posts", { include: ["title"] }); // not a reference field await myna.entries.list("posts", { fields: ["nope"] }); ``` Passing no type parameter keeps the previous untyped behavior, so adopting this is opt-in and nothing breaks by ignoring it. ## Type mapping | Field type | Generated type | |---|---| | `text` | `string`, or a string-literal union when `enum` is set | | `slug` | `string` | | `markdown` | `string` | | `number` | `number` | | `boolean` | `boolean` | | `date` / `datetime` | `string` (ISO date / ISO datetime with offset) | | `json` | `JsonValue` | | `asset` | `string` (asset id), `string[]` when `multiple` | | `reference` | `string` (entry id), `string[]` when `multiple` | | `object` | inline object type from its nested fields | | `list` | `T[]` where `T` follows the same mapping for the item kind (enum text items are parenthesized unions; object items are inline object types) | References and assets are ids, not expanded documents — resolve them through the SDK or API. ## Recommended workflow Commit the generated file. It is stable output, so diffs stay meaningful and CI can verify it is current: ```bash $ myna schema push $ myna types generate --out src/myna-types.ts $ git add myna/ src/myna-types.ts && git commit -m "Add subtitle to posts" ``` Regenerate after every [schema push](/schema/deploying); a clean `git diff` on the generated file after regenerating means your types match the schemas. The file header marks it as generated — do not edit it by hand. ## Next - [Deploying schema changes](/schema/deploying) — the diff/push flow that these types track. - [Quickstart](/getting-started/quickstart) — end-to-end setup including type generation.