TypeScript annotates Zod type with any instead of inferred type

1 day ago 1
ARTICLE AD BOX

Given a library exporting Zod schemas (living in their own separate files) defining a recursive table header structure.

Starting with a root list of columns:

const columnsConfigurationSchema = z.array(columnConfigurationSchema).min(1);

where each list item is either a group or a leaf element:

const columnConfigurationSchema = z.union([ columnGroupConfigurationSchema, leafColumnConfigurationSchema, ]);

A single group element contains a new child list of columns:

const columnGroupConfigurationSchema = z.object({ groupField: z.string(), // a field that only exists for groups get children() { return columnsConfigurationSchema; }, });

A leaf column can have different types based on its type field:

const leafColumnConfigurationSchema = z.discriminatedUnion("type", [ workItemColumnConfigurationSchema, computedColumnConfigurationSchema, ]);

I also added a check function if a given list item is a column group:

function isColumnGroup(column: ColumnConfiguration): column is ColumnGroupConfiguration { return "children" in column; }

The problem is that this recursive schema might be too complex for TypeScript. I created a function for testing purposes:

function getColspan(columnConfiguration: ColumnConfiguration) { if (!isColumnGroup(columnConfiguration)) { return 1; } return columnConfiguration.children.reduce( (colspanSum, currentChildColumn) => colspanSum + getColspan(currentChildColumn), 0 ); }

and columnConfiguration.children is of type any although I would expect it to be of type ColumnsConfiguration.

StackBlitz

How can I fix the schema definition so TypeScript can infer the correct types?

Read Entire Article