@@ -225,6 +225,10 @@ export enum ParameterType {
225225 * Resolved according to the config directory unless it starts with `**`, after skipping any leading `!` and `#` characters.
226226 */
227227 GlobArray ,
228+ /**
229+ * An unopinionated object that preserves default settings unless explicitly overridden
230+ */
231+ Object ,
228232 /**
229233 * An object with true/false flags
230234 */
@@ -341,6 +345,20 @@ export interface MixedDeclarationOption extends DeclarationOptionBase {
341345 validate ?: ( value : unknown ) => void ;
342346}
343347
348+ export interface ObjectDeclarationOption extends DeclarationOptionBase {
349+ type : ParameterType . Object ;
350+
351+ /**
352+ * If not specified defaults to undefined.
353+ */
354+ defaultValue ?: unknown ;
355+
356+ /**
357+ * An optional validation function that validates a potential value of this option.
358+ * The function must throw an Error if the validation fails and should do nothing otherwise.
359+ */
360+ validate ?: ( value : unknown ) => void ;
361+ }
344362export interface MapDeclarationOption < T > extends DeclarationOptionBase {
345363 type : ParameterType . Map ;
346364
@@ -378,6 +396,7 @@ export type DeclarationOption =
378396 | NumberDeclarationOption
379397 | BooleanDeclarationOption
380398 | MixedDeclarationOption
399+ | ObjectDeclarationOption
381400 | MapDeclarationOption < unknown >
382401 | ArrayDeclarationOption
383402 | FlagsDeclarationOption < Record < string , boolean > > ;
@@ -388,6 +407,7 @@ export interface ParameterTypeToOptionTypeMap {
388407 [ ParameterType . Number ] : number ;
389408 [ ParameterType . Boolean ] : boolean ;
390409 [ ParameterType . Mixed ] : unknown ;
410+ [ ParameterType . Object ] : unknown ;
391411 [ ParameterType . Array ] : string [ ] ;
392412 [ ParameterType . PathArray ] : string [ ] ;
393413 [ ParameterType . ModuleArray ] : string [ ] ;
@@ -503,6 +523,12 @@ const converters: {
503523 option . validate ?.( value ) ;
504524 return value ;
505525 } ,
526+ [ ParameterType . Object ] ( value , option , _configPath , oldValue ) {
527+ option . validate ?.( value ) ;
528+ if ( typeof oldValue !== "undefined" )
529+ value = { ...( oldValue as { } ) , ...( value as { } ) } ;
530+ return value ;
531+ } ,
506532 [ ParameterType . Flags ] ( value , option ) {
507533 if ( typeof value === "boolean" ) {
508534 value = Object . fromEntries (
@@ -596,6 +622,9 @@ const defaultGetters: {
596622 [ ParameterType . Mixed ] ( option ) {
597623 return option . defaultValue ;
598624 } ,
625+ [ ParameterType . Object ] ( option ) {
626+ return option . defaultValue ;
627+ } ,
599628 [ ParameterType . Array ] ( option ) {
600629 return option . defaultValue ?. slice ( ) ?? [ ] ;
601630 } ,
0 commit comments