-
Notifications
You must be signed in to change notification settings - Fork 0
Description
Describe the bug
TypeGen generates types that include _type for named object types used as non-array fields, but Sanity's Content Lake does not store the _type field for these objects when there's only one possible type. This causes a mismatch between the generated TypeScript types and the actual query results.
To Reproduce
-
Install the
@sanity/tableplugin which defines a named object typetable -
Create a schema that uses
tableas a direct object field (not in an array):// add-table.ts import { defineField, defineType } from 'sanity' export default defineType({ name: 'addTable', title: 'Table', type: 'object', fields: [ defineField({ name: 'title', title: 'Title', type: 'string', }), defineField({ name: 'table', title: 'Table', type: 'table', // references the named type from @sanity/table }), ], })
-
Run
sanity schema extractandsanity typegen generate -
Query the data using GROQ and observe the actual result vs generated types
Expected behavior
The generated type should match the actual stored data. Since Sanity doesn't store _type for non-array object fields with a single possible type, the generated type should not include it.
Actual behavior
TypeGen generates:
export type Table = {
_type: 'table' // ← Generated, but NOT in actual data
rows?: Array<
{
_key: string
} & TableRow
>
}But the actual GROQ query result is:
{
"_type": "addTable",
"table": {
"rows": [
{
"_key": "d5794e3b-e44d-42b8-b0de-cbdb6032b9df",
"_type": "tableRow",
"cells": ["Column 1", "Column 2", "Column 3"]
}
]
}
}Note that:
addTablehas_type: "addTable"✓tabledoes NOT have_type: "table"✗ (mismatch with generated type)tableRow(in array) has_type: "tableRow"✓
Analysis
The extracted schema correctly includes _type for the table type:
{
"name": "table",
"type": "type",
"value": {
"type": "object",
"attributes": {
"_type": {
"type": "objectAttribute",
"value": {
"type": "string",
"value": "table"
}
},
"rows": { ... }
}
}
}However, Sanity's Content Lake optimizes storage by not storing _type for non-array object fields when there's only one possible type (since it can be inferred from the schema). TypeGen should account for this behavior.
Workaround
Use TypeScript utility types to remove _type from the affected types:
import type { Except } from 'type-fest'
import type { Table } from 'types/sanity.types'
type ActualTable = Except<Table, '_type'>Which versions of Sanity are you using?
`@sanity/client`: ^7.8.2
`@sanity/table`: ^1.1.3
`sanity`: ^4.10.2
Which versions of Node.js / npm are you running?
npm: 10.9.2
Node: v22.16.0
What operating system are you using?
Linux (Ubuntu 22.04.5 LTS) running inside WSL 2 (v2.4.13.0) within Windows (Windows 11 Pro, version 24H2, OS build 26100.7623)
Additional context
Might be related to #20 which also involves TypeGen generating incorrect _type values that don't match actual query results.
The distinction seems to be:
- Array members →
_typeIS stored (needed for type discrimination when multiple types are possible) - Non-array object fields with single type →
_typeis NOT stored (optimization, can be inferred)
TypeGen should understand this storage behavior and generate types accordingly, perhaps by marking _type as optional for non-array object fields, or omitting it entirely when only one type is possible.