@@ -443,6 +443,7 @@ function transformSchemaObjectCore(schemaObject: SchemaObject, options: Transfor
443443 if (
444444 ( "properties" in schemaObject && schemaObject . properties && Object . keys ( schemaObject . properties ) . length ) ||
445445 ( "additionalProperties" in schemaObject && schemaObject . additionalProperties ) ||
446+ ( "patternProperties" in schemaObject && schemaObject . patternProperties ) ||
446447 ( "$defs" in schemaObject && schemaObject . $defs )
447448 ) {
448449 // properties
@@ -542,34 +543,54 @@ function transformSchemaObjectCore(schemaObject: SchemaObject, options: Transfor
542543 ) ;
543544 }
544545
545- // additionalProperties
546- if ( schemaObject . additionalProperties || options . ctx . additionalProperties ) {
547- const hasExplicitAdditionalProperties =
548- typeof schemaObject . additionalProperties === "object" && Object . keys ( schemaObject . additionalProperties ) . length ;
549- const addlType = hasExplicitAdditionalProperties
550- ? transformSchemaObject ( schemaObject . additionalProperties as SchemaObject , options )
551- : UNKNOWN ;
552- return tsIntersection ( [
553- ...( coreObjectType . length ? [ ts . factory . createTypeLiteralNode ( coreObjectType ) ] : [ ] ) ,
554- ts . factory . createTypeLiteralNode ( [
555- ts . factory . createIndexSignature (
556- /* modifiers */ tsModifiers ( {
557- readonly : options . ctx . immutable ,
558- } ) ,
559- /* parameters */ [
560- ts . factory . createParameterDeclaration (
561- /* modifiers */ undefined ,
562- /* dotDotDotToken */ undefined ,
563- /* name */ ts . factory . createIdentifier ( "key" ) ,
564- /* questionToken */ undefined ,
565- /* type */ STRING ,
566- ) ,
567- ] ,
568- /* type */ addlType ,
569- ) ,
570- ] ) ,
571- ] ) ;
546+ // additionalProperties / patternProperties
547+ const hasExplicitAdditionalProperties =
548+ typeof schemaObject . additionalProperties === "object" && Object . keys ( schemaObject . additionalProperties ) . length ;
549+ const hasImplicitAdditionalProperties =
550+ schemaObject . additionalProperties === true ||
551+ ( typeof schemaObject . additionalProperties === "object" &&
552+ Object . keys ( schemaObject . additionalProperties ) . length === 0 ) ;
553+ const hasExplicitPatternProperties =
554+ typeof schemaObject . patternProperties === "object" && Object . keys ( schemaObject . patternProperties ) . length ;
555+ const stringIndexTypes = [ ] ;
556+ if ( hasExplicitAdditionalProperties ) {
557+ stringIndexTypes . push ( transformSchemaObject ( schemaObject . additionalProperties as SchemaObject , options ) ) ;
572558 }
559+ if ( hasImplicitAdditionalProperties || ( ! schemaObject . additionalProperties && options . ctx . additionalProperties ) ) {
560+ stringIndexTypes . push ( UNKNOWN ) ;
561+ }
562+ if ( hasExplicitPatternProperties ) {
563+ for ( const [ _ , v ] of getEntries ( schemaObject . patternProperties ?? { } , options . ctx ) ) {
564+ stringIndexTypes . push ( transformSchemaObject ( v , options ) ) ;
565+ }
566+ }
567+
568+ if ( stringIndexTypes . length === 0 ) {
569+ return coreObjectType . length ? ts . factory . createTypeLiteralNode ( coreObjectType ) : undefined ;
570+ }
571+
572+ const stringIndexType = tsUnion ( stringIndexTypes ) ;
573+
574+ return tsIntersection ( [
575+ ...( coreObjectType . length ? [ ts . factory . createTypeLiteralNode ( coreObjectType ) ] : [ ] ) ,
576+ ts . factory . createTypeLiteralNode ( [
577+ ts . factory . createIndexSignature (
578+ /* modifiers */ tsModifiers ( {
579+ readonly : options . ctx . immutable ,
580+ } ) ,
581+ /* parameters */ [
582+ ts . factory . createParameterDeclaration (
583+ /* modifiers */ undefined ,
584+ /* dotDotDotToken */ undefined ,
585+ /* name */ ts . factory . createIdentifier ( "key" ) ,
586+ /* questionToken */ undefined ,
587+ /* type */ STRING ,
588+ ) ,
589+ ] ,
590+ /* type */ stringIndexType ,
591+ ) ,
592+ ] ) ,
593+ ] ) ;
573594 }
574595
575596 return coreObjectType . length ? ts . factory . createTypeLiteralNode ( coreObjectType ) : undefined ;
0 commit comments