From caec7cd270bef59bb29f17cdc38824ee66a26578 Mon Sep 17 00:00:00 2001 From: Alberto Marchetti Date: Tue, 31 Oct 2023 09:12:55 +0200 Subject: [PATCH] Fix the edge case where defaults are treated as required but we explicitely want to pass the `optional` flag. --- src/__tests__/defaults/defaults.ts | 17 ++++++++++++++++- src/parse.ts | 5 ++++- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/src/__tests__/defaults/defaults.ts b/src/__tests__/defaults/defaults.ts index 4f898124..d2973a68 100644 --- a/src/__tests__/defaults/defaults.ts +++ b/src/__tests__/defaults/defaults.ts @@ -18,7 +18,10 @@ describe('Test behaviour for optional fields with supplied defaults', function ( }), alt2: Joi.alternatives() .try(Joi.string(), Joi.number(), Joi.object({ val: Joi.boolean().default(true) })) - .default({ val: false }) + .default({ val: false }), + strOptional: Joi.string().default('Test').optional(), + numOptional: Joi.number().default(1).optional(), + boolOptional: Joi.boolean().default(true).optional() }); it('Test defaults as optional and excluded from types', function () { @@ -36,11 +39,14 @@ describe('Test behaviour for optional fields with supplied defaults', function ( arr?: number[]; arr2?: string[]; bool?: boolean; + boolOptional?: boolean; num?: number; + numOptional?: number; obj?: { val?: string; }; str?: string; + strOptional?: string; }`); }); it('Test defaults as required and excluded from types', function () { @@ -61,11 +67,14 @@ describe('Test behaviour for optional fields with supplied defaults', function ( arr: number[]; arr2: string[]; bool: boolean; + boolOptional?: boolean; num: number; + numOptional?: number; obj: { val?: string; }; str: string; + strOptional?: string; }`); }); it('Test defaults as optional and included in types', function () { @@ -83,11 +92,14 @@ describe('Test behaviour for optional fields with supplied defaults', function ( arr?: [1,2,3] | number; arr2?: ["X","Y","Z"] | string; bool?: true | boolean; + boolOptional?: true | boolean; num?: 1 | number; + numOptional?: 1 | number; obj?: {"val":"Test"} | { val?: string; }; str?: "Test" | string; + strOptional?: "Test" | string; }`); }); it('Test defaults as required and included in types', function () { @@ -105,11 +117,14 @@ describe('Test behaviour for optional fields with supplied defaults', function ( arr: [1,2,3] | number; arr2: ["X","Y","Z"] | string; bool: true | boolean; + boolOptional?: true | boolean; num: 1 | number; + numOptional?: 1 | number; obj: {"val":"Test"} | { val?: string; }; str: "Test" | string; + strOptional?: "Test" | string; }`); }); }); diff --git a/src/parse.ts b/src/parse.ts index a5f985c4..bf8f7a31 100644 --- a/src/parse.ts +++ b/src/parse.ts @@ -32,7 +32,10 @@ function getCommonDetails( const isReadonly = getIsReadonly(details); let required; - if (presence === 'required' || (settings.treatDefaultedOptionalAsRequired && value !== undefined)) { + if ( + presence === 'required' || + (settings.treatDefaultedOptionalAsRequired && presence !== 'optional' && value !== undefined) + ) { required = true; } else if (presence === 'optional') { required = false;