@@ -188,9 +188,11 @@ export type KeyToDeclaration<K extends keyof TypeDocOptionMap> =
188188 : TypeDocOptionMap [ K ] extends string [ ]
189189 ? ArrayDeclarationOption
190190 : unknown extends TypeDocOptionMap [ K ]
191- ? MixedDeclarationOption
191+ ? MixedDeclarationOption | ObjectDeclarationOption
192192 : TypeDocOptionMap [ K ] extends ManuallyValidatedOption < unknown >
193- ? MixedDeclarationOption & { validate ( value : unknown ) : void }
193+ ?
194+ | ( MixedDeclarationOption & { validate ( value : unknown ) : void } )
195+ | ( ObjectDeclarationOption & { validate ( value : unknown ) : void } )
194196 : TypeDocOptionMap [ K ] extends Record < string , boolean >
195197 ? FlagsDeclarationOption < TypeDocOptionMap [ K ] >
196198 : TypeDocOptionMap [ K ] extends Record < string | number , infer U >
@@ -225,6 +227,10 @@ export enum ParameterType {
225227 * Resolved according to the config directory unless it starts with `**`, after skipping any leading `!` and `#` characters.
226228 */
227229 GlobArray ,
230+ /**
231+ * An unopinionated object that preserves default settings unless explicitly overridden
232+ */
233+ Object ,
228234 /**
229235 * An object with true/false flags
230236 */
@@ -341,6 +347,20 @@ export interface MixedDeclarationOption extends DeclarationOptionBase {
341347 validate ?: ( value : unknown ) => void ;
342348}
343349
350+ export interface ObjectDeclarationOption extends DeclarationOptionBase {
351+ type : ParameterType . Object ;
352+
353+ /**
354+ * If not specified defaults to undefined.
355+ */
356+ defaultValue ?: unknown ;
357+
358+ /**
359+ * An optional validation function that validates a potential value of this option.
360+ * The function must throw an Error if the validation fails and should do nothing otherwise.
361+ */
362+ validate ?: ( value : unknown ) => void ;
363+ }
344364export interface MapDeclarationOption < T > extends DeclarationOptionBase {
345365 type : ParameterType . Map ;
346366
@@ -378,6 +398,7 @@ export type DeclarationOption =
378398 | NumberDeclarationOption
379399 | BooleanDeclarationOption
380400 | MixedDeclarationOption
401+ | ObjectDeclarationOption
381402 | MapDeclarationOption < unknown >
382403 | ArrayDeclarationOption
383404 | FlagsDeclarationOption < Record < string , boolean > > ;
@@ -388,6 +409,7 @@ export interface ParameterTypeToOptionTypeMap {
388409 [ ParameterType . Number ] : number ;
389410 [ ParameterType . Boolean ] : boolean ;
390411 [ ParameterType . Mixed ] : unknown ;
412+ [ ParameterType . Object ] : unknown ;
391413 [ ParameterType . Array ] : string [ ] ;
392414 [ ParameterType . PathArray ] : string [ ] ;
393415 [ ParameterType . ModuleArray ] : string [ ] ;
@@ -409,7 +431,8 @@ const converters: {
409431 [ K in ParameterType ] : (
410432 value : unknown ,
411433 option : DeclarationOption & { type : K } ,
412- configPath : string
434+ configPath : string ,
435+ oldValue : unknown
413436 ) => ParameterTypeToOptionTypeMap [ K ] ;
414437} = {
415438 [ ParameterType . String ] ( value , option ) {
@@ -503,6 +526,12 @@ const converters: {
503526 option . validate ?.( value ) ;
504527 return value ;
505528 } ,
529+ [ ParameterType . Object ] ( value , option , _configPath , oldValue ) {
530+ option . validate ?.( value ) ;
531+ if ( typeof oldValue !== "undefined" )
532+ value = { ...( oldValue as { } ) , ...( value as { } ) } ;
533+ return value ;
534+ } ,
506535 [ ParameterType . Flags ] ( value , option ) {
507536 if ( typeof value === "boolean" ) {
508537 value = Object . fromEntries (
@@ -554,16 +583,18 @@ const converters: {
554583export function convert (
555584 value : unknown ,
556585 option : DeclarationOption ,
557- configPath : string
586+ configPath : string ,
587+ oldValue ?: unknown
558588) : unknown {
559589 const _converters = converters as Record <
560590 ParameterType ,
561- ( v : unknown , o : DeclarationOption , c : string ) => unknown
591+ ( v : unknown , o : DeclarationOption , c : string , ov : unknown ) => unknown
562592 > ;
563593 return _converters [ option . type ?? ParameterType . String ] (
564594 value ,
565595 option ,
566- configPath
596+ configPath ,
597+ oldValue
567598 ) ;
568599}
569600
@@ -596,6 +627,9 @@ const defaultGetters: {
596627 [ ParameterType . Mixed ] ( option ) {
597628 return option . defaultValue ;
598629 } ,
630+ [ ParameterType . Object ] ( option ) {
631+ return option . defaultValue ;
632+ } ,
599633 [ ParameterType . Array ] ( option ) {
600634 return option . defaultValue ?. slice ( ) ?? [ ] ;
601635 } ,
0 commit comments