Skip to content

Commit

Permalink
Merge branch 'marlonbernardes-fix/default-behaviour' into v2
Browse files Browse the repository at this point in the history
  • Loading branch information
Colin McDonnell committed Sep 27, 2020
2 parents 0170e3c + c87fe1c commit 9c73441
Show file tree
Hide file tree
Showing 5 changed files with 54 additions and 26 deletions.
2 changes: 1 addition & 1 deletion README.md
Expand Up @@ -1596,7 +1596,7 @@ const stringWithDefault = z.transformer(
);
```

Equivalently you can express this using the built-in `.default()` method, available on all Zod schemas.
Equivalently you can express this using the built-in `.default()` method, available on all Zod schemas. The default value will be used if and only if the schema is `undefined`.

```ts
z.string().default('default value');
Expand Down
26 changes: 26 additions & 0 deletions src/__tests__/transformer.test.ts
Expand Up @@ -59,6 +59,32 @@ test('default', () => {
expect(data).toEqual('asdf');
});

test('default when property is null or undefined', () => {
const data = z
.object({
foo: z
.boolean()
.nullable()
.default(true),
bar: z.boolean().default(true),
})
.parse({ foo: null });

expect(data).toEqual({ foo: null, bar: true });
});

test('default with falsy values', () => {
const schema = z.object({
emptyStr: z.string().default('def'),
zero: z.number().default(5),
falseBoolean: z.boolean().default(true),
});
const input = { emptyStr: '', zero: 0, falseBoolean: true };
const output = schema.parse(input);
// defaults are not supposed to be used
expect(output).toEqual(input);
});

test('object typing', () => {
const t1 = z.object({
stringToNumber,
Expand Down
28 changes: 15 additions & 13 deletions src/parser.ts
Expand Up @@ -375,20 +375,22 @@ export const ZodParser = (schema: z.ZodType<any>) => (
if (!keyValidator) continue;

// check if schema and value are both optional
try {
keyValidator.parse(undefined, {
...params,
path: [...params.path, key],
});

// const keyDataType = getParsedType(data[key]);
if (!Object.keys(data).includes(key)) {
// schema is optional
// data is undefined
// don't explicity add undefined to outut
continue;
}
} catch (err) {}
// const keyDataType = getParsedType(data[key]);
if (!Object.keys(data).includes(key)) {
try {
const output = keyValidator.parse(undefined, {
...params,
path: [...params.path, key],
});
if (output === undefined) {
// schema is optional
// data is undefined
// don't explicity add undefined to outut
continue;
}
} catch (err) {}
}

objectPromises[key] = new PseudoPromise().then(() => {
try {
Expand Down
22 changes: 11 additions & 11 deletions src/playground.ts
@@ -1,17 +1,17 @@
import * as z from '.';

const run = async () => {
const SNamedEntity = z.object({
id: z.string(),
set: z.string().optional(),
unset: z.string().optional(),
});
const result = await SNamedEntity.parse({
id: 'asdf',
set: undefined,
});
console.log(result);
console.log(Object.keys(result));
const data = z
.object({
foo: z
.boolean()
.nullable()
.default(true),
bar: z.boolean().default(true),
})
.parse({ foo: null });

console.log(data);
};
run();

Expand Down
2 changes: 1 addition & 1 deletion src/types/base.ts
Expand Up @@ -324,7 +324,7 @@ export abstract class ZodType<
def: T,
) => ZodTransformer<Opt, this> = def => {
return ZodTransformer.create(this.optional(), this, (x: any) => {
return (x || def) as any;
return x === undefined ? def : x;
}) as any;
};

Expand Down

0 comments on commit 9c73441

Please sign in to comment.