diff --git a/src/object.ts b/src/object.ts index aaabfc61..39e921cc 100644 --- a/src/object.ts +++ b/src/object.ts @@ -419,17 +419,23 @@ export default class ObjectSchema< if (this.fields[key]) picked[key] = this.fields[key]; } - return this.setFields<{ [K in TKey]: TIn[K] }, TDefault>(picked); + return this.setFields<{ [K in TKey]: TIn[K] }, TDefault>( + picked, + this._excludedEdges.filter( + ([a, b]) => keys.includes(a as TKey) && keys.includes(b as TKey), + ), + ); } omit(keys: readonly TKey[]) { - const fields = { ...this.fields }; + const remaining: TKey[] = []; - for (const key of keys) { - delete fields[key]; + for (const key of Object.keys(this.fields) as TKey[]) { + if (keys.includes(key)) continue; + remaining.push(key); } - return this.setFields, TDefault>(fields); + return this.pick(remaining); } from(from: string, to: keyof TIn, alias?: boolean) { diff --git a/test/object.ts b/test/object.ts index 2911bf60..553c679e 100644 --- a/test/object.ts +++ b/test/object.ts @@ -1121,4 +1121,48 @@ describe('Object types', () => { await inst.omit(['age', 'name']).validate({ color: 'mauve' }), ).toEqual({ color: 'mauve' }); }); + + it('should pick and omit with excluded edges', async () => { + const inst = object().shape( + { + a1: string().when('a2', { + is: undefined, + then: (schema) => schema.required(), + }), + a2: string().when('a1', { + is: undefined, + then: (schema) => schema.required(), + }), + a3: string().required(), + }, + [['a1', 'a2']], + ); + + expect( + inst.pick(['a1', 'a2']).isValid({ + a1: undefined, + a2: 'over9000', + }), + ).resolves.toEqual(true); + + expect( + inst.pick(['a1', 'a3']).isValid({ + a1: 'required', + a3: 'asfasf', + }), + ).resolves.toEqual(true); + + expect( + inst.omit(['a1', 'a2']).isValid({ + a3: 'asfasf', + }), + ).resolves.toEqual(true); + + expect( + inst.omit(['a1']).isValid({ + a1: undefined, + a3: 'asfasf', + }), + ).resolves.toEqual(false); + }); });