Mike Hogan
Mike Hogan

Reputation: 10603

zod (or toZod): how to model "type" field in discriminated union

I have this type:

export interface ConnectorForModel {
    _type: "connector.for.model",
    connectorDefinitionId: string
}

I want to model is as a zod schema. Actually I am using toZod, like this:

export const ConnectorForModelZod: toZod<ConnectorForModel> = z.object({
    _type: z.literal("connector.for.model"),
    connectorDefinitionId: z.string()
});

And I get this type error:

Type 'ZodLiteral<"connector.for.model">' is not assignable to type 'never'.

Whats the right way to express this?

Upvotes: 2

Views: 3207

Answers (1)

Souperman
Souperman

Reputation: 9836

I think the quickest way to get this working is with ZodType:

import { z } from "zod";

export interface ConnectorForModel {
  _type: "connector.for.model";
  connectorDefinitionId: string;
}

export const ConnectorForModelZod: z.ZodType<ConnectorForModel> = z.object({
  _type: z.literal("connector.for.model"),
  connectorDefinitionId: z.string()
});

Aside: I tend to define my types from my zod schemas rather than the other way around. If you don't have control over the type that you're working with then the given approach is the way to go, but you could potentially avoid writing the same code twice using z.TypeOf on the zod schema

type ConnectorForModel = z.TypeOf<typeof ConnectorForModelZod>;

This type would be equivalent to your interface.

Upvotes: 2

Related Questions