Getting TypeScript definitions from defineType function in Sanity schema builder

6 replies
Last updated: Feb 25, 2023
Ahoj, is there a way to get a schema typescript definition from the 'defineType' function? I tried using whatever it returns but all I get is :
const environment: {
    type: "document";
    name: "environment";
} & Omit<DocumentDefinition, "preview"> & {
    preview?: PreviewConfig<{
        title: string;
        subheader: string;
        image: string;
    }, Record<"image" | "title" | "subheader", any>> | undefined;
}
There should be a slug and a bunch of other stuff on there?
🤔
AI Update

I see the issue! You're trying to get the TypeScript type for your document data from defineType, but defineType returns the schema definition type, not the actual document type. That's why you're seeing DocumentDefinition instead of your fields like slug.

Here's the correct approach using Sanity's official type generation:

Use sanity typegen (Official Method)

Sanity's official type generation tool creates proper TypeScript types for all your documents. Run these two commands:

# Extract your schema to a JSON file
npx sanity schema extract

# Generate TypeScript types
npx sanity typegen generate

This creates a sanity.types.ts file with types for all your documents:

// Now you can import and use your types
import type { Environment } from './sanity.types'

// Environment will have all your fields:
// { _id, _type, _createdAt, _updatedAt, slug, title, etc. }

The generated types include all your custom fields (like slug) plus Sanity's system fields (_id, _type, _createdAt, etc.).

For GROQ queries, wrap them with defineQuery and the typegen will also generate result types:

import { defineQuery } from 'groq'

const query = defineQuery(`*[_type == "environment"][0]`)

// After running typegen, you get typed results
const result = await client.fetch(query) // fully typed!

Using the Types

Once generated, you can use them throughout your codebase:

import type { Environment } from './sanity.types'
import { client } from './sanity/client'

// Type-safe document creation
await client.create<Environment>({
  _type: "environment",
  slug: { current: "my-slug" },
  title: "My Environment",
  // TypeScript will catch missing required fields!
})

Why Not Use defineType Return Type?

The defineType function returns a schema definition object (metadata about your schema), not the runtime document type. It's meant for configuring your Studio, not for typing your actual content data.

Community Alternatives

If you prefer a different approach, there are community tools like sanity-codegen that offer alternative type generation methods, but sanity typegen is the officially supported and recommended solution.

Pro tip: Run sanity typegen generate whenever you change your schema to keep types in sync. You can also add it to your build process or set up a file watcher for automatic regeneration.

Ok I think this isnt a thing yet.This looks promising though, anyone had any success with it?

https://github.com/saiichihashimoto/sanity-typed-schema-builder
are you looking to gen types based on your schema? https://www.sanity.io/plugins/sanity-codegen
or are you trying to get types from sanity https://www.npmjs.com/package/@sanity/types
The former! I assumed the defineType function would also build a type to reuse elsewhere. I'll give the codegen a go! Cheers

Sanity – Build the way you think, not the way your CMS thinks

Sanity is the developer-first content operating system that gives you complete control. Schema-as-code, GROQ queries, and real-time APIs mean no more workarounds or waiting for deployments. Free to start, scale as you grow.

Was this answer helpful?