Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion src/SwaggerProvider.DesignTime/DefinitionCompiler.fs
Original file line number Diff line number Diff line change
Expand Up @@ -483,7 +483,8 @@ type DefinitionCompiler(schema: OpenApiDocument, provideNullable, useDateOnly: b
| _ when
resolvedType = Some JsonSchemaType.Object
&& not(isNull schemaObj.AdditionalProperties)
-> // Dictionary ->
&& (schemaObj.Properties |> isNull || schemaObj.Properties.Count = 0)
-> // Dictionary (only when no explicit properties are also defined)
ns.ReleaseNameReservation tyName
let elSchema = schemaObj.AdditionalProperties

Expand Down
35 changes: 35 additions & 0 deletions tests/SwaggerProvider.Tests/Schema.ArrayAndMapTypeMappingTests.fs
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,41 @@ let ``additionalProperties boolean maps to Map<string, bool>``() =
ty
|> shouldEqual(typedefof<Map<string, obj>>.MakeGenericType(typeof<string>, typeof<bool>))

// ── Object with both properties and additionalProperties is not a Map ─────────
// When a schema has explicit `properties` alongside `additionalProperties`, the
// type should be compiled as an object (preserving the declared properties), not
// silently reduced to a Map that discards them.

[<Fact>]
let ``object with properties and additionalProperties compiles to object type not Map``() =
let schemaStr =
"""openapi: "3.0.0"
info:
title: MixedAdditionalPropsTest
version: "1.0.0"
paths: {}
components:
schemas:
TestType:
type: object
properties:
Value:
type: object
properties:
Name:
type: string
additionalProperties:
type: integer
"""

let ty = compileSchemaAndGetValueType schemaStr
// Should be an object type (not a generic Map)
ty.IsGenericType |> shouldEqual false

ty.GetProperties()
|> Array.exists(fun p -> p.Name = "Name")
|> shouldEqual true

// ── Array of $ref objects ─────────────────────────────────────────────────────

[<Fact>]
Expand Down
Loading