diff --git a/src/schema/object/group_builder.ts b/src/schema/object/group_builder.ts index 68a31e9..07f537a 100644 --- a/src/schema/object/group_builder.ts +++ b/src/schema/object/group_builder.ts @@ -11,7 +11,7 @@ import { ObjectGroup } from './group.js' import { CamelCase } from '../camelcase_types.js' import { GroupConditional } from './conditional.js' import { OTYPE, COTYPE, ITYPE } from '../../symbols.js' -import type { FieldContext, SchemaTypes } from '../../types.js' +import type { FieldContext, SchemaTypes, UndefinedOptional } from '../../types.js' /** * Create an object group. Groups are used to conditionally merge properties @@ -32,15 +32,15 @@ group.if = function groupIf>( ) { return new GroupConditional< Properties, - { + UndefinedOptional<{ [K in keyof Properties]: Properties[K][typeof ITYPE] - }, - { + }>, + UndefinedOptional<{ [K in keyof Properties]: Properties[K][typeof OTYPE] - }, - { + }>, + UndefinedOptional<{ [K in keyof Properties as CamelCase]: Properties[K][typeof COTYPE] - } + }> >(conditon, properties) } @@ -52,14 +52,14 @@ group.else = function groupElse>( ) { return new GroupConditional< Properties, - { + UndefinedOptional<{ [K in keyof Properties]: Properties[K][typeof ITYPE] - }, - { + }>, + UndefinedOptional<{ [K in keyof Properties]: Properties[K][typeof OTYPE] - }, - { + }>, + UndefinedOptional<{ [K in keyof Properties as CamelCase]: Properties[K][typeof COTYPE] - } + }> >(() => true, properties) } diff --git a/tests/types/types.spec.ts b/tests/types/types.spec.ts index c021837..ade4d1f 100644 --- a/tests/types/types.spec.ts +++ b/tests/types/types.spec.ts @@ -606,6 +606,61 @@ test.group('Types | Object groups', () => { >() }) + test('infer types with optional children', ({ expectTypeOf }) => { + const guideSchema = vine.group([ + vine.group.if((data) => vine.helpers.isTrue(data.hiring_guide), { + hiring_guide: vine.literal(true), + guide_name: vine.string(), + fees: vine.string().optional(), + }), + vine.group.if(() => true, { + hiring_guide: vine.literal(false), + }), + ]) + + const schema = vine + .object({ + visitor_name: vine.string().optional(), + }) + .merge(guideSchema) + .optional() + + type InputsSchema = InferInput + expectTypeOf().toEqualTypeOf< + | ({ + visitor_name?: string | undefined | null + } & ( + | { + hiring_guide: true + guide_name: string + fees?: string | undefined | null + } + | { + hiring_guide: false + } + )) + | null + | undefined + >() + + type Schema = Infer + expectTypeOf().toEqualTypeOf< + | ({ + visitor_name?: string | undefined + } & ( + | { + hiring_guide: true + guide_name: string + fees?: string | undefined + } + | { + hiring_guide: false + } + )) + | undefined + >() + }) + test('infer types with multiple groups', ({ expectTypeOf }) => { const guideSchema = vine.group([ vine.group.if((data) => vine.helpers.isTrue(data.hiring_guide), {