End-to-end type safety with Sanity TypeGen
How Turbo Start Sanity threads generated types from schema to GROQ to React, so a renamed field breaks the build instead of shipping undefined to production.
The nicest thing about the Turbo Start Sanity type story is that you never hand-write a content type. Types flow from the Sanity schema, through your GROQ queries, into narrow React props — and if any link in that chain breaks, TypeScript tells you at build time rather than a user finding undefined in production.
The generation flow
Two steps turn your schema into types. First an extract pass reads the deployed schema; then a generate pass matches every defineQuery against that schema and writes concrete result types:
Order matters. If you change a schema and run the type generation without extracting first, the query types are generated against a stale schema snapshot and silently go out of date. Extract, then generate, every time the schema moves.
defineQuery is the linchpin
Because every query is declared with defineQuery from next-sanity, TypeGen can statically analyse it and produce an exact result type — not a hand-guessed interface, but the real shape the query returns. Rename a field in the schema and forget to update the projection, and the generated type changes, which ripples into every component that reads it.
Derive narrow types, never duplicate
Frontend types are never re-declared by hand. They are extracted from the generated query result types with TypeScript utilities:
That Extract helper is what lets the page-builder dispatcher assert block as PagebuilderType<"hero"> and get the precise props for a hero block. Duplicating the shape by hand would defeat the entire point: the moment the schema and the copy disagree, you are lying to the compiler.
Why it changes how you work
- A schema rename becomes a compile error in every consumer, not a runtime surprise.
- Autocomplete on query results is real, because the type is the query's actual output.
- Refactoring is safe: the build is a genuine safety net, so you can move fast without a QA pass catching field typos.
The rule to internalise is small: after any schema change, extract then regenerate, and let the types fan out from there. Do that, and the gap between "what Sanity stores" and "what React expects" simply cannot open.