Giter Club home page Giter Club logo

zod-to-ts's Introduction

zod-to-ts

generate TypeScript types from your Zod schema

Installation

npm install zod-to-ts zod typescript

Usage

import { z } from 'zod'
import { zodToTs } from 'zod-to-ts'

// define your Zod schema
const UserSchema = z.object({
	username: z.string(),
	age: z.number(),
	inventory: z.object({
		name: z.string(),
		itemId: z.number(),
	}).array(),
})

// pass schema and name of type/identifier
const { node } = zodToTs(UserSchema, 'User')

result:

{
  username: string
  age: number
  inventory: {
    name: string
    itemId: number
  }[]
}

You must pass in the identifier User or it will default to Identifier. This is necessary to handle cases like recursive types and native enums. zodToTs() only returns the type value, not the actual type declaration. If you want to add an identifier to the type and create a type declaration, you can use the createTypeAlias() utility:

import { createTypeAlias, zodToTs } from 'zod-to-ts'

const identifier = 'User'
const { node } = zodToTs(UserSchema, identifier)
const typeAlias = createTypeAlias(
	node,
	identifier,
	// optionally pass a comment
	// comment: UserSchema.description
)

result:

type User = {
	username: string
}

zodToTs() and createTypeAlias() return a TS AST nodes, so if you want to get the node as a string, you can use the printNode() utility.

zodToTs():

import { printNode, zodToTs } from 'zod-to-ts'

const identifier = 'User'
const { node } = zodToTs(UserSchema, identifier)
const nodeString = printNode(node)

result:

"{
  username: string
  age: number
  inventory: {
    name: string
    itemId: number
  }[]
}"

createTypeAlias():

import { createTypeAlias, printNode, zodToTs } from 'zod-to-ts'

const identifier = 'User'
const { node } = zodToTs(UserSchema, identifier)
const typeAlias = createTypeAlias(node, identifier)
const nodeString = printNode(typeAlias)

result:

"type User = {
  username: string
  age: number
  inventory: {
    name: string
    itemId: number
  }[]
}"

Overriding Types

You can use withGetType to override a type, which is useful when more information is needed to determine the actual type. Unfortunately, this means working with the TS AST:

import { z } from 'zod'
import { withGetType, zodToTs } from 'zod-to-ts'

const DateSchema = withGetType(
	z.instanceof(Date),
	(ts) => ts.factory.createIdentifier('Date'),
)

const ItemSchema = z.object({
	name: z.string(),
	date: DateSchema,
})

const { node } = zodToTs(ItemSchema, 'Item')

result without withGetType override:

type Item = {
	name: string
	date: any
}

result with override:

type Item = {
	name: string
	date: Date
}

TypeScript AST Viewer can help a lot with this if you are having trouble referencing something. It even provides copy-pastable code!

Special Cases

Lazy types default to referencing the root type (User in the following example). It is impossible to determine what it is referencing otherwise.

// Zod cannot infer types when you use the z.lazy
// so you must define it
import { z } from 'zod'
type User = {
	username: string
	friends: User[]
}

const UserSchema: z.ZodSchema<User> = z.object({
	username: z.string(),
	friends: z.lazy(() => UserSchema).array(),
})

const { node } = zodToTs(UserSchema, 'User')

result:

type User = {
	username: string
	friends: User[]
}

But what happens when the schema looks like this?

type User = {
	username: string
	item: {
		name: string
		itemId: string
	}
	friends: User[]
}

// essentially when you are referencing a different field
// and not the root type
const friendItems = z.lazy(() => UserSchema.item).array()

const UserSchema: z.ZodSchema<User> = z.object({
	username: z.string(),
	item: z.object({
		name: z.string(),
		id: z.number(),
	}),
	friendItems,
})

const { node } = zodToTs(UserSchema, 'User')

result:

{
  username: string
  item: {
    name: string
    id: number
  }
  friendItems: User[]
}

friendItems will still have the User type even though it is actually referencing UserSchema["item"]. You must provide the actual type using withGetType:

import { z } from 'zod'
import { withGetType } from 'zod-to-ts'
type User = {
	username: string
	item: {
		name: string
		id: number
	}
	friends: User[]
}

const friendItems: z.Schema<User['item'][]> = withGetType(
	z.lazy(() => UserSchema.item).array(),
	// return a TS AST node
	(ts, identifier) =>
		ts.factory.createIndexedAccessTypeNode(
			ts.factory.createTypeReferenceNode(
				ts.factory.createIdentifier(identifier),
				undefined,
			),
			ts.factory.createLiteralTypeNode(ts.factory.createStringLiteral('item')),
		),
)

const UserSchema: z.ZodSchema<User> = z.object({
	username: z.string(),
	item: z.object({
		name: z.string(),
		id: z.number(),
	}),
	friendItems,
})

const { node } = zodToTs(UserSchema, 'User')

result:

{
  username: string
  item: {
    name: string
    id: number
  }
  friendItems: User['item'][]
}

z.enum() is always preferred, but sometimes z.nativeEnum() is necessary. z.nativeEnum() works similarly to z.lazy() in that the identifier of the enum cannot be determined:

import { z } from 'zod'
import { withGetType } from 'zod-to-ts'

enum Fruit {
  Apple = 'apple',
  Banana = 'banana',
  Cantaloupe = 'cantaloupe',
}

const fruitNativeEnum: = z.nativeEnum(
  Fruit,
)

const TreeSchema = z.object({
  fruit: fruitNativeEnum,
})

result:

{
  fruit: unknown
}

There are three ways to solve this: provide an identifier to it or resolve all the enums inside zodToTs().

Option 1 - providing an identifier using withGetType():

import { z } from 'zod'
import { withGetType, zodToTs } from 'zod-to-ts'

enum Fruit {
	Apple = 'apple',
	Banana = 'banana',
	Cantaloupe = 'cantaloupe',
}

const fruitNativeEnum = withGetType(
	z.nativeEnum(
		Fruit,
	),
	// return an identifier that will be used on the enum type
	(ts) => ts.factory.createIdentifier('Fruit'),
)

const TreeSchema = z.object({
	fruit: fruitNativeEnum,
})

const { node } = zodToTs(TreeSchema)

result:

{
  fruit: Fruit
}

Option 2 - resolve enums. This is the same as before, but you just need to pass an option:

const TreeTSType = zodToTs(TreeSchema, undefined, { nativeEnums: 'resolve' })

result:

{
  node: {
    fruit: Fruit
  },
  store: {
    nativeEnums: [
      enum Fruit {
        Apple = 'apple',
        Banana = 'banana',
        Cantaloupe = 'cantaloupe',
      }
    ]
  }
}

Note: These are not the actual values, they are TS representation. The actual values are TS AST nodes.

This option allows you to embed the enums before the schema without actually depending on an external enum type.

Option 3 - convert to union. This is the same as how ZodEnum created by z.enum([...]) is handled, but need to pass an option:

const { node } = zodToTs(TreeSchema, undefined, {
	nativeEnums: 'union',
})

result:

{
  fruit: 'apple' | 'banana' | 'cantaloupe'
}

Note: These are not the actual values, they are TS representation. The actual values are TS AST nodes.

zod-to-ts's People

Contributors

mordv avatar noahdavey avatar renovate-bot avatar renovate[bot] avatar robintail avatar sachinraja avatar shaketbaby avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

zod-to-ts's Issues

Does not handle ZodDiscriminatedUnion

Using the TypeScript handbook's example:

type Shape =
   | { kind: "circle"; radius: number }
   | { kind: "square"; x: number }
   | { kind: "triangle"; x: number; y: number };

const shape = z.discriminatedUnion("kind", [
   z.object({ kind: z.literal("circle"), radius: z.number() }),
   z.object({ kind: z.literal("square"), x: z.number() }),
   z.object({ kind: z.literal("triangle"), x: z.number(), y: z.number() }),
]);

const { node } = zodToTs(shape, 'Shape');
const nodeString = printNode(node);
console.log("type Shape =", nodeString);  // gives "type Shape = any"

What's the use case?

Curious about the use case of this project. Zod itself is all about having types statically available at compile time. So why would one need to generate types from zod schema in the first place?

`nativeEnum()` value with description

It seems that adding a description to the nativeEnum() value field outputs unknown as shown below.
Is this a bug or expected behavior?

enum-value.mjs
import { z } from 'zod';
import { printNode, withGetType, zodToTs } from 'zod-to-ts';

const Enum = z.nativeEnum({
    ONE: 1,
    TWO: 2,
}).describe('Comment for Enum');

withGetType(Enum, ts => ts.factory.createIdentifier('Enum'));

const schema = z.object({
    key: Enum,
});

const { node } = zodToTs(schema, { resolveNativeEnums: true });
console.log(printNode(node));
// {
//     /** Comment for Enum */
//     key: Enum;
// }

enum-value-with-description.mjs
import { z } from 'zod';
import { printNode, withGetType, zodToTs } from 'zod-to-ts';

const Enum = z.nativeEnum({
    ONE: 1,
    TWO: 2,
});

withGetType(Enum, ts => ts.factory.createIdentifier('Enum'));

const schema = z.object({
    key: Enum.describe('Comment for key'),
});

const { node } = zodToTs(schema, { resolveNativeEnums: true });
console.log(printNode(node));
// {
//     /** Comment for key */
//     key: unknown;
// }

Typescript should be regular dependency

Hello @sachinraja ,

After upgrading to TS 4.9, which is specified as a peer dependency of your library, I noticed the following warnings:

DeprecationWarning: 'createTypeAliasDeclaration' has been deprecated since v4.8.0. Decorators are no longer supported for this function. Callers should switch to an overload that does not accept a 'decorators' parameter.

    > 56 |         const inputAlias = createTypeAlias( ... );

DeprecationWarning: 'createParameterDeclaration' has been deprecated since v4.8.0. Decorators have been combined with modifiers. Callers should switch to an overload that does not accept a 'decorators' parameter.

    > 49 |         const response = zodToTs( ... );

DeprecationWarning: 'createIndexSignature' has been deprecated since v4.8.0. Decorators are no longer supported for this function. Callers should switch to an overload that does not accept a 'decorators' parameter.

    > 49 |         const response = zodToTs( ... );

Since you're operating the TS' factory methods that are subject for changes, I believe that Typescript should be the regular dependency of the package, not dev+peer. Thus, your implementation would operate the exact version of Typescript that is needed.

I'm going to create a PR for this.

Debug Failure. Unhandled SyntaxKind: Unknown

Getting this error when using with typescript 5.2.2:

      "message": "Debug Failure. Unhandled SyntaxKind: Unknown.",
      "stack":
          Error: Debug Failure. Unhandled SyntaxKind: Unknown.
              at pipelineEmitWithHintWorker (/Users/alex/dev/statsig/node_modules/.pnpm/[email protected]/node_modules/typescript/lib/typescript.js:113284:13)
              at pipelineEmitWithHint (/Users/alex/dev/statsig/node_modules/.pnpm/[email protected]/node_modules/typescript/lib/typescript.js:112828:9)
              at pipelineEmitWithComments (/Users/alex/dev/statsig/node_modules/.pnpm/[email protected]/node_modules/typescript/lib/typescript.js:116619:7)
              at pipelineEmit (/Users/alex/dev/statsig/node_modules/.pnpm/[email protected]/node_modules/typescript/lib/typescript.js:112777:7)
              at emit (/Users/alex/dev/statsig/node_modules/.pnpm/[email protected]/node_modules/typescript/lib/typescript.js:112745:7)
              at emitTypeAnnotation (/Users/alex/dev/statsig/node_modules/.pnpm/[email protected]/node_modules/typescript/lib/typescript.js:115569:9)
              at emitIndexSignature (/Users/alex/dev/statsig/node_modules/.pnpm/[email protected]/node_modules/typescript/lib/typescript.js:113613:7)
              at pipelineEmitWithHintWorker (/Users/alex/dev/statsig/node_modules/.pnpm/[email protected]/node_modules/typescript/lib/typescript.js:112903:20)
              at pipelineEmitWithHint (/Users/alex/dev/statsig/node_modules/.pnpm/[email protected]/node_modules/typescript/lib/typescript.js:112828:9)
              at pipelineEmitWithComments (/Users/alex/dev/statsig/node_modules/.pnpm/[email protected]/node_modules/typescript/lib/typescript.js:116619:7)
              at pipelineEmit (/Users/alex/dev/statsig/node_modules/.pnpm/[email protected]/node_modules/typescript/lib/typescript.js:112777:7)
              at emit (/Users/alex/dev/statsig/node_modules/.pnpm/[email protected]/node_modules/typescript/lib/typescript.js:112745:7)
              at emitListItemWithParenthesizerRule (/Users/alex/dev/statsig/node_modules/.pnpm/[email protected]/node_modules/typescript/lib/typescript.js:117065:5)
              at emitNodeListItems (/Users/alex/dev/statsig/node_modules/.pnpm/[email protected]/node_modules/typescript/lib/typescript.js:115776:9)
              at emitNodeList (/Users/alex/dev/statsig/node_modules/.pnpm/[email protected]/node_modules/typescript/lib/typescript.js:115715:9)
              at emitList (/Users/alex/dev/statsig/node_modules/.pnpm/[email protected]/node_modules/typescript/lib/typescript.js:115673:7)
              at emitTypeLiteral (/Users/alex/dev/statsig/node_modules/.pnpm/[email protected]/node_modules/typescript/lib/typescript.js:113695:7)
              at pipelineEmitWithHintWorker (/Users/alex/dev/statsig/node_modules/.pnpm/[email protected]/node_modules/typescript/lib/typescript.js:112915:20)
              at pipelineEmitWithHint (/Users/alex/dev/statsig/node_modules/.pnpm/[email protected]/node_modules/typescript/lib/typescript.js:112828:9)
              at pipelineEmitWithComments (/Users/alex/dev/statsig/node_modules/.pnpm/[email protected]/node_modules/typescript/lib/typescript.js:116619:7)
              at pipelineEmit (/Users/alex/dev/statsig/node_modules/.pnpm/[email protected]/node_modules/typescript/lib/typescript.js:112777:7)
              at emit (/Users/alex/dev/statsig/node_modules/.pnpm/[email protected]/node_modules/typescript/lib/typescript.js:112745:7)
              at emitListItemWithParenthesizerRule (/Users/alex/dev/statsig/node_modules/.pnpm/[email protected]/node_modules/typescript/lib/typescript.js:117065:5)
              at emitNodeListItems (/Users/alex/dev/statsig/node_modules/.pnpm/[email protected]/node_modules/typescript/lib/typescript.js:115776:9)
              at emitNodeList (/Users/alex/dev/statsig/node_modules/.pnpm/[email protected]/node_modules/typescript/lib/typescript.js:115715:9)
              at emitList (/Users/alex/dev/statsig/node_modules/.pnpm/[email protected]/node_modules/typescript/lib/typescript.js:115673:7)
              at emitUnionType (/Users/alex/dev/statsig/node_modules/.pnpm/[email protected]/node_modules/typescript/lib/typescript.js:113727:7)
              at pipelineEmitWithHintWorker (/Users/alex/dev/statsig/node_modules/.pnpm/[email protected]/node_modules/typescript/lib/typescript.js:112923:20)
              at pipelineEmitWithHint (/Users/alex/dev/statsig/node_modules/.pnpm/[email protected]/node_modules/typescript/lib/typescript.js:112828:9)
              at pipelineEmitWithComments (/Users/alex/dev/statsig/node_modules/.pnpm/[email protected]/node_modules/typescript/lib/typescript.js:116619:7)
              at pipelineEmit (/Users/alex/dev/statsig/node_modules/.pnpm/[email protected]/node_modules/typescript/lib/typescript.js:112777:7)
              at print (/Users/alex/dev/statsig/node_modules/.pnpm/[email protected]/node_modules/typescript/lib/typescript.js:112690:7)
              at writeNode (/Users/alex/dev/statsig/node_modules/.pnpm/[email protected]/node_modules/typescript/lib/typescript.js:112533:7)
              at Object.printNode (/Users/alex/dev/statsig/node_modules/.pnpm/[email protected]/node_modules/typescript/lib/typescript.js:112497:7)
              at printNode (/Users/alex/dev/statsig/node_modules/.pnpm/[email protected]_pkihvv7tkirfyj5v6rn4ddr4b4/node_modules/zod-to-ts/dist/index.cjs:42:18)

This happened when calling printNode(zodToTs(z.record(z.unknown())).node) and other records (ex. z.record(z.string(), z.string()).optional())

Invalid identifiers should be quoted

I ran into this because I'm parsing JSON that has keys containing the dash ("-") character.

Simple example:

const simpleTest = z.object({
   "needs-quotes": z.string(),
});
const testRet = ztt.zodToTs(simpleTest, "Test");
const testAlias = ztt.createTypeAlias(testRet.node, "TestType");
console.log(ztt.printNode(testAlias));

The above code will output

type TestType = {
    needs-quotes: string;
};

...which isn't legal TypeScript.

Default values in jsdoc

I would like the output to include default types, such as when you have a schema like this:

z.object({
  thing: z.string().default("hello");
})
// => 
type Schema = {
  /** @default "hello" */
  thing: string;
}

README should include printNode?

Hi - this is a great idea!

But I spent a little time confused by the README - Just getting the node results in a typescript AST, but then the result is shown a printed source code.

I think the output in the README is more representative of calling printNode?

If you agree I can submit a PR to fit it

Dependency Dashboard

This issue lists Renovate updates and detected dependencies. Read the Dependency Dashboard docs to learn more.

Open

These updates have all been created already. Click a checkbox below to force a retry/rebase of any.

Detected dependencies

github-actions
.github/workflows/test.yaml
  • actions/checkout v3
  • pnpm/action-setup v2
  • actions/setup-node v3
npm
package.json
  • typescript ^4.9.4 || ^5.0.2
  • zod ^3
  • pnpm 8.15.7

  • Check this box to trigger a request for Renovate to run again on this repository

.catch() evaluates to any

Currently, this: Test: z.string().nullable().catch(null) evaluates to Test?: any, although it can only be string | null. Do you see a possibility to improve this?

Reproducible example:

const TestSchema = z.object({
    Test: z.string().nullable().catch(null)
});

console.log((printNode(zodToTs(TestSchema).node)));

Using `z.instanceOf()` to reference a class type

Hi there! Thanks for this cool library. I'm trying to use it as a codegen tool to generate types based on BigQuery schema definitions and output them to a file.

I have a use case such as this:

const schema = z.object({
  name: z.string(),
  type: z.instanceof(BigQueryTimestamp),
})

const { node } = zodToTs(schema)
console.log(printNode(node))

Which results in a generated string of:

{
    name: string,
    type: any
}

What I would like is something which results in a generated string of:

{
    name: string,
    type: BigQueryTimestamp
}

And then I could manually add import { BigQueryTimestamp } from '@google-cloud/bigquery' to the top of the output file.

Is there a way I specify the identifier for type? Or is this something to do with when it's printed? Not super familiar with how the underlying typescript stuff works but happy to dig into it and contribute if you can point me in the right direction. Thanks!

Get input type?

Hi!

Maybe I missed it, but I do not see any way to get the equivalent of zod.input<Type> as a string with zodToTs. Is this something that is considered on the todo list?

Thank you a lot in advance

export option in createTypeAlias

Would be great if createTypeAlias supported an options parameter that allows you to export the typeAlias.

Eg:

export const createTypeAlias = (node: ts.TypeNode, identifier: string, options: (string | { comment?: string; exportType?: boolean }) = {}) => {
  const { comment, exportType } = typeof options === 'string' ? { comment: options, exportType: false } : options;
  const modifiers = exportType ? [f.createModifier(ts.SyntaxKind.ExportKeyword)] : [];
  const typeAlias = f.createTypeAliasDeclaration(
    modifiers ,
    f.createIdentifier(identifier),
    undefined,
    node,
  )

  if (comment) {
    addJsDocComment(typeAlias, comment)
  }

  return typeAlias
}

Unable to get the correct type when I used `z.transform()`

When I use transform to convert the data type, I am not able to obtain the correct type.

import { z } from 'zod';
import { printNode, zodToTs } from 'zod-to-ts';

// define your Zod schema
const UserSchema = z.object({
  username: z.string(),
  age: z.number(),
  avatar: z.string().transform((value) => {
    // convert...
    return {
      src: value,
      width: 100,
      height: 100,
    };
  }),
});

// pass schema and name of type/identifier
const { node } = zodToTs(UserSchema, 'User');

const code = printNode(node);

console.log(code);
{
    username: string;
    age: number;
    avatar: string;
}

Conversion of `z.nativeEnum()` with negative number fails on TS v5.4

index.mjs
import { z } from 'zod'
import { printNode, withGetType, zodToTs } from 'zod-to-ts'

const $enum = withGetType(z.nativeEnum({
    NEG_1: -1,
    POS_1: +1,
}), ts => ts.factory.createIdentifier('Enum'));

const { store } = zodToTs($enum, 'Enum', { nativeEnums: 'resolve' });
const node = store.nativeEnums[0];

console.log(printNode(node));

When I ran the above script with TypeScript v5.4, I got the following error.

Note

This error did not occur on TypeScript v5.3.

$ node index.mjs
C:\path\to\cwd\node_modules\typescript\lib\typescript.js:21074
      Debug.assert(text.charCodeAt(0) !== 45 /* minus */, "Negative numbers should be created in combination with createPrefixUnaryExpression");
            ^

Error: Debug Failure. False expression: Negative numbers should be created in combination with createPrefixUnaryExpression
    at Object.createNumericLiteral (C:\path\to\cwd\node_modules\typescript\lib\typescript.js:21074:13)
    at file:///path/to/cwd/node_modules/zod-to-ts/dist/index.js:198:58
    at Array.map (<anonymous>)
    at zodToTsNode (file:///path/to/cwd/node_modules/zod-to-ts/dist/index.js:197:61)
    at zodToTs (file:///path/to/cwd/node_modules/zod-to-ts/dist/index.js:67:16)
    at file:///path/to/cwd/index.mjs:9:19
    at ModuleJob.run (node:internal/modules/esm/module_job:218:25)
    at async ModuleLoader.import (node:internal/modules/esm/loader:329:24)
    at async loadESM (node:internal/process/esm_loader:28:7)
    at async handleMainPromise (node:internal/modules/run_main:113:12)

Node.js v20.11.1

diff of package.json
   "dependencies": {
-    "typescript": "5.3",
+    "typescript": "5.4",
     "zod": "^3.22.4",
     "zod-to-ts": "^1.2.0"
   },

Is there any workaround other than continuing to use the old TypeScript?

can convert preprocess to ts

z.preprocess(
                (a) => parseInt(z.string().parse(a), 10),
                z.number().positive().max(100)
              ),

error:

console.log
    ZodError: [
      {
        "code": "invalid_type",
        "expected": "string",
        "received": "undefined",
        "path": [],
        "message": "Required"
      }
    ]
        at handleResult (/Users/owner/Documents/source-code/private/express-zod-api/node_modules/zod/lib/types.js:29:23)
        at ZodString.safeParse (/Users/owner/Documents/source-code/private/express-zod-api/node_modules/zod/lib/types.js:140:16)
        at ZodString.parse (/Users/owner/Documents/source-code/private/express-zod-api/node_modules/zod/lib/types.js:120:29)
        at Object.transform (/Users/owner/Documents/source-code/private/express-zod-api/tests/unit/client.spec.ts:19:44)
        at ZodEffects._parse (/Users/owner/Documents/source-code/private/express-zod-api/node_modules/zod/lib/types.js:2261:38)
        at ZodEffects._parseSync (/Users/owner/Documents/source-code/private/express-zod-api/node_modules/zod/lib/types.js:109:29)
        at ZodEffects.safeParse (/Users/owner/Documents/source-code/private/express-zod-api/node_modules/zod/lib/types.js:139:29)
        at ZodEffects.isOptional (/Users/owner/Documents/source-code/private/express-zod-api/node_modules/zod/lib/types.js:276:21)
        at /Users/owner/Documents/source-code/private/express-zod-api/node_modules/zod-to-ts/dist/index.cjs:141:81
        at Array.map (<anonymous>)

Request: option to include description as comments

Given:

import { z } from 'zod'
import { zodToTs } from 'zod-to-ts'

// define your Zod schema
const UserSchema = z.object({
	username: z.string().describe("User's name"),
	age: z.number().describe("User's age"),
	inventory: z.object({
		name: z.string().describe("Item name"),
		itemId: z.number().describe("Item ID number"),
	}).array(),
})

// pass schema and name of type/identifier
const { node } = zodToTs(UserSchema, 'User')
const nodeString = printNode(node, { descriptions: true })

Result:

"{
  username: string  // User's name
  age: number  // User's age
  inventory: {
    name: string  // Item name
    itemId: number  // Item ID number
  }[]
}"

Obviously in this case the descriptions are purely redundant but for the use cases I have in mind the comments could add real value.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.