Skip to content

Commit

Permalink
Better Optional Handling (#11)
Browse files Browse the repository at this point in the history
* Add question token for optional properties

* Update tests to reflect correct handling of optionals

* update snapshots

Co-authored-by: Sachin Raja <sachinraja2349@gmail.com>
  • Loading branch information
NoahDavey and sachinraja committed Apr 26, 2022
1 parent ed65bcc commit 813872d
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 8 deletions.
8 changes: 6 additions & 2 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -85,12 +85,16 @@ const zodToTsNode = (
const properties = Object.entries(zod._def.shape())

const members: ts.TypeElement[] = properties.map(([key, value]) => {
const type = zodToTsNode(value as ZodTypeAny, ...otherArgs)
const nextZodNode = value as ZodTypeAny
const type = zodToTsNode(nextZodNode, ...otherArgs)

const { typeName: nextZodNodeTypeName } = nextZodNode._def
const isOptional = nextZodNodeTypeName === 'ZodOptional' || nextZodNode.isOptional()

return f.createPropertySignature(
undefined,
f.createIdentifier(key),
undefined,
isOptional ? f.createToken(ts.SyntaxKind.QuestionToken) : undefined,
type,
)
})
Expand Down
39 changes: 37 additions & 2 deletions test/modifiers.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,47 @@ import { printNodeTest } from './utils'

const OptionalStringSchema = z.string().optional()

describe('z.optional()', () => {
const { node } = zodToTs(OptionalStringSchema)
const ObjectWithOptionals = z.object({
optional: OptionalStringSchema,
required: z.string(),
transform: z.number().optional().transform((arg) => arg),
or: z.number().optional().or(z.string()),
tuple: z.tuple([
z.string().optional(),
z.number(),
z.object({
optional: z.string().optional(),
required: z.string(),
}),
]).optional(),
})

describe('z.optional()', () => {
it('outputs correct typescript', () => {
const { node } = zodToTs(OptionalStringSchema)
expect(printNodeTest(node)).toMatchInlineSnapshot('"string | undefined"')
})

it('for optionals should output ?: property as well as undefined union', () => {
const { node } = zodToTs(ObjectWithOptionals)

expect(printNodeTest(node)).toMatchInlineSnapshot(`
"{
optional?: string | undefined;
required: string;
transform?: number | undefined;
or?: (number | undefined) | string;
tuple?: [
string | undefined,
number,
{
optional?: string | undefined;
required: string;
}
] | undefined;
}"
`)
})
})

const NullableUsernameSchema = z.object({
Expand Down
8 changes: 4 additions & 4 deletions test/primitive.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,11 @@ describe('PrimitiveSchema', () => {
age: number;
isAdmin: boolean;
createdAt: Date;
undef: undefined;
undef?: undefined;
nu: null;
vo: void | undefined;
an: any;
unknow: unknown;
vo?: void | undefined;
an?: any;
unknow?: unknown;
nev: never;
}"
`)
Expand Down

0 comments on commit 813872d

Please sign in to comment.