Skip to content

Commit

Permalink
Fixed explicit undefined values for optional keys. Fixes #161
Browse files Browse the repository at this point in the history
  • Loading branch information
Colin McDonnell committed Sep 27, 2020
1 parent 54f9dda commit 0170e3c
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 14 deletions.
1 change: 1 addition & 0 deletions README.md
Expand Up @@ -66,6 +66,7 @@ Some other great aspects:
- Immutability: methods (i.e. `.optional()` return a new instance
- Concise, chainable interface
- Functional approach: [parse, don't validate](https://lexi-lambda.github.io/blog/2019/11/05/parse-don-t-validate/)
- Works with plain JavaScript too! You don't need to use TypeScript.

# Sponsorship

Expand Down
13 changes: 13 additions & 0 deletions src/__tests__/object.test.ts
Expand Up @@ -236,3 +236,16 @@ test('catchall overrides strict', () => {
asdf: 1234,
});
});

test('test that optional keys are unset', 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,
});
expect(Object.keys(result)).toEqual(['id', 'set']);
});
21 changes: 19 additions & 2 deletions src/parser.ts
Expand Up @@ -367,19 +367,36 @@ export const ZodParser = (schema: z.ZodType<any>) => (

for (const key of shapeKeys) {
const keyValidator = shapeKeys.includes(key)
? def.shape()[key]
? shape[key]
: !(def.catchall instanceof ZodNever)
? def.catchall
: undefined;

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) {}

objectPromises[key] = new PseudoPromise().then(() => {
try {
return keyValidator.parse(data[key], {
const parsedValue = keyValidator.parse(data[key], {
...params,
path: [...params.path, key],
});
return parsedValue;
} catch (err) {
if (err instanceof ZodError) {
const zerr: ZodError = err;
Expand Down
37 changes: 25 additions & 12 deletions src/playground.ts
@@ -1,17 +1,30 @@
import * as z from '.';
// import { Scalars } from './helpers/primitive';

const obj = z.object({
primitiveTuple: z.tuple([z.string(), z.number()]),
nonprimitiveTuple: z.tuple([z.string(), z.number().array()]),
});
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));
};
run();

type obj = z.infer<typeof obj>;
// export const T = z.object({
// test: z.string().optional(),
// });

const prim = obj.primitives();
console.log(prim.shape);
const nonprim = obj.nonprimitives();
console.log(nonprim.shape);
// .primitives();
// console.log(T.safeParse({}));

// type t1 = [[string, number]] extends [Scalars] ? true : false;
// const r = T.safeParse({});

// if (r.success) {
// console.log(JSON.stringify(r.data));
// }

// console.log(JSON.stringify({ test: undefined, test2: undefined }, null, 2));

0 comments on commit 0170e3c

Please sign in to comment.