diff --git a/src/typeschema/core/field-builder.ts b/src/typeschema/core/field-builder.ts index 1334f3b3..b554de62 100644 --- a/src/typeschema/core/field-builder.ts +++ b/src/typeschema/core/field-builder.ts @@ -10,6 +10,7 @@ import type { CodegenLog } from "@root/utils/log"; import { packageMetaToFhir } from "@typeschema/types"; import type { BindingIdentifier, + DiscriminatorType, EnumDefinition, Field, FieldSlice, @@ -199,8 +200,16 @@ const computeTypeDiscriminatorMatch = ( * Used when a slice has an empty match but the discriminator values are nested deeper * (e.g., component slices in BP where the discriminator crosses a nested slicing boundary). */ +const validDiscriminatorTypes = new Set(["value", "exists", "pattern", "type", "profile"]); + +// TODO: Update type in FHIR Schema to prevent this casting. +const toDiscriminators = ( + raw: { type: string; path: string }[] | undefined, +): { type: DiscriminatorType; path: string }[] => + (raw ?? []).filter((d) => validDiscriminatorTypes.has(d.type)) as { type: DiscriminatorType; path: string }[]; + const computeMatchFromSchema = ( - discriminators: Array<{ type?: string; path: string }>, + discriminators: { type: DiscriminatorType; path: string }[], schema: FHIRSchemaElement | undefined, ): Record | undefined => { if (!schema || !discriminators || discriminators.length === 0) return undefined; @@ -230,7 +239,7 @@ const buildSlicing = (element: FHIRSchemaElement): FieldSlicing | undefined => { min: slice.min, max: slice.max, match: isEmptyMatch(slice.match) - ? computeMatchFromSchema(slicing.discriminator ?? [], slice.schema) + ? computeMatchFromSchema(toDiscriminators(slicing.discriminator), slice.schema) : (slice.match as Record | undefined), required, excluded, @@ -239,7 +248,7 @@ const buildSlicing = (element: FHIRSchemaElement): FieldSlicing | undefined => { } return { - discriminator: slicing.discriminator, + discriminator: toDiscriminators(slicing.discriminator), rules: slicing.rules, ordered: slicing.ordered, slices: Object.keys(slices).length > 0 ? slices : undefined, diff --git a/src/typeschema/types.ts b/src/typeschema/types.ts index 74824326..013affaa 100644 --- a/src/typeschema/types.ts +++ b/src/typeschema/types.ts @@ -211,8 +211,10 @@ export interface ProfileTypeSchema { nested?: NestedType[]; } +export type DiscriminatorType = "value" | "exists" | "pattern" | "type" | "profile"; + export interface FieldSlicing { - discriminator?: Array<{ type?: string; path: string }>; + discriminator?: { type: DiscriminatorType; path: string }[]; rules?: string; ordered?: boolean; slices?: Record;