Search code examples
zodtypedoc

Can I get prettier types out of Zod inferred types in my Typedoc documentation?


My problem

I'm first using z.infer to produce types from Zod schemas and then Typedoc to generate documentation for those types, but the output is less than ideal in a few ways:

  • The types come out as type aliases in the form TypeName: z.infer<typeof schemaName>, which isn't helpful in itself (thankfully schemaName is clickable)
  • The schemas come out with all sorts of Zod types in the way, e.g. ZodObject<{ name: ZodOptional<ZodString>}> instead of the expected { name?: string }
  • Optional object properties in schemas come out as e.g. name: undefined | string rather than name?: string or even (optional) name?: string, which Typedoc does for regular (non-Zod) types.

Example

Here's an example (from repro repo):

index.ts

import z from 'zod'

export const userSchema = z.object({
  name: z.string().optional()
})

export type ZodUser = z.infer<typeof userSchema>

export type TypescriptUser = {
  name?: string
}

Once I run Typedoc on this, it's fairly obvious that the results are better with TypescriptUser than with ZodUser:

ZodUser

file:///…/zod-typedoc-ugly/docs/types/ZodUser.html:

ZodUser: z.infer<typeof userSchema>

file:///…/zod-typedoc-ugly/docs/variables/userSchema.html:

userSchema: ZodObject<{
    name: ZodOptional<ZodString>;
}, "strip", ZodTypeAny, {
    name: undefined | string;
}, {
    name: undefined | string;
}> = ...

VS


TypescriptUser

file:///…/zod-typedoc-ugly/docs/types/TypescriptUser.html:

TypescriptUser: {
    name?: string;
}

Seeking Solution

I'm looking for a way to get the advantages of Zod (I can use the schema responsible for the type at runtime to validate inputs) along with the simpler docs of zod-less Typescript types. I understand I can maintain the two separately, but I would rather that be automatic and not introduce a risk for both of these versions to fall out of sync.

Is there a better way, a workaround or an alternative here?


Solution

  • As of approximately 5 minutes ago, yes. There is a way. typedoc-plugin-zod can be used to make TypeDoc use the inferred type instead of the type node when converting the z.infer type aliases. It will also replace the original schema declaration's type to refer to the ZodUser type.

    (obvious disclaimer, I just wrote this)