···1313 bar: 'foo' | 'bar' | 'baz';
1414};
15151616-export type Baz = Qux & {
1616+export type Baz = Omit<Qux, 'id'> & {
1717 foo: number;
1818 bar: Date;
1919 baz: 'foo' | 'bar' | 'baz';
+5
packages/openapi-ts/src/ir/types.d.ts
···183183 */
184184 logicalOperator?: 'and' | 'or';
185185 /**
186186+ * When used with `$ref` or `symbolRef`, specifies properties to omit from the referenced schema.
187187+ * Useful for handling discriminator property conflicts in allOf compositions.
188188+ */
189189+ omit?: ReadonlyArray<string>;
190190+ /**
186191 * When type is `object`, `patternProperties` can be used to define a schema
187192 * for properties that match a specific regex pattern.
188193 */
···8080};
81818282/**
8383- * Gets all discriminator values for a schema and its children in the inheritance hierarchy.
8484- * For intermediate schemas (those that are extended by others), returns a union of all values.
8383+ * Gets the discriminator value for a schema.
8484+ * Returns only the schema's own discriminator value, not child values.
8585 */
8686const getAllDiscriminatorValues = ({
8787- context,
8887 discriminator,
8988 schemaRef,
9089}: {
9191- context: Context;
9290 discriminator: NonNullable<SchemaObject['discriminator']>;
9391 schemaRef: string;
9492}): Array<string> => {
···10199 if (mappedSchemaRef === schemaRef) {
102100 // This is the current schema's own value
103101 values.push(value);
104104- continue;
105105- }
106106-107107- // Check if the mapped schema extends the current schema
108108- const mappedSchema = context.resolveRef<SchemaObject>(mappedSchemaRef);
109109- if (mappedSchema.allOf) {
110110- for (const item of mappedSchema.allOf) {
111111- if ('$ref' in item && item.$ref === schemaRef) {
112112- // This schema extends the current schema, add its value
113113- values.push(value);
114114- break;
115115- }
116116- }
117102 }
118103 }
119104···521506 for (const { discriminator, isRequired, values } of discriminatorsToAdd) {
522507 // Get all discriminator values including children for union types
523508 const allValues = getAllDiscriminatorValues({
524524- context,
525509 discriminator,
526510 schemaRef: state.$ref!,
527511 });
···543527 logicalOperator: 'or',
544528 }
545529 : valueSchemas[0]!;
530530+531531+ // Check if any $ref schemas in schemaItems have this discriminator property
532532+ // If yes, mark them to omit it to avoid conflicts
533533+ for (const item of schemaItems) {
534534+ if (item.$ref || item.symbolRef) {
535535+ // Check if the referenced schema has this property
536536+ const hasProperty = (() => {
537537+ if (!item.$ref) return false;
538538+ try {
539539+ const refSchema = context.resolveRef<SchemaObject>(item.$ref);
540540+ // Check if the discriminator property exists in the ref schema
541541+ return (
542542+ refSchema.properties?.[discriminator.propertyName] !==
543543+ undefined ||
544544+ (refSchema.allOf &&
545545+ refSchema.allOf.some((allOfItem) => {
546546+ const resolved =
547547+ '$ref' in allOfItem
548548+ ? context.resolveRef<SchemaObject>(allOfItem.$ref)
549549+ : allOfItem;
550550+ return (
551551+ resolved.properties?.[discriminator.propertyName] !==
552552+ undefined
553553+ );
554554+ }))
555555+ );
556556+ } catch {
557557+ return false;
558558+ }
559559+ })();
560560+561561+ if (hasProperty) {
562562+ // Mark this ref to omit the discriminator property
563563+ if (!item.omit) {
564564+ item.omit = [discriminator.propertyName];
565565+ } else if (!item.omit.includes(discriminator.propertyName)) {
566566+ item.omit = [...item.omit, discriminator.propertyName];
567567+ }
568568+ }
569569+ }
570570+ }
546571547572 // Find the inline schema (non-$ref) to merge the discriminator property into
548573 // The inline schema should be the last non-$ref item in schemaItems
···8484};
85858686/**
8787- * Gets all discriminator values for a schema and its children in the inheritance hierarchy.
8888- * For intermediate schemas (those that are extended by others), returns a union of all values.
8787+ * Gets the discriminator value for a schema.
8888+ * Returns only the schema's own discriminator value, not child values.
8989 */
9090const getAllDiscriminatorValues = ({
9191- context,
9291 discriminator,
9392 schemaRef,
9493}: {
9595- context: Context;
9694 discriminator: NonNullable<SchemaObject['discriminator']>;
9795 schemaRef: string;
9896}): Array<string> => {
···105103 if (mappedSchemaRef === schemaRef) {
106104 // This is the current schema's own value
107105 values.push(value);
108108- continue;
109109- }
110110-111111- // Check if the mapped schema extends the current schema
112112- const mappedSchema = context.resolveRef<SchemaObject>(mappedSchemaRef);
113113- if (mappedSchema.allOf) {
114114- for (const item of mappedSchema.allOf) {
115115- if (item.$ref && item.$ref === schemaRef) {
116116- // This schema extends the current schema, add its value
117117- values.push(value);
118118- break;
119119- }
120120- }
121106 }
122107 }
123108···602587 for (const { discriminator, isRequired, values } of discriminatorsToAdd) {
603588 // Get all discriminator values including children for union types
604589 const allValues = getAllDiscriminatorValues({
605605- context,
606590 discriminator,
607591 schemaRef: state.$ref!,
608592 });
···624608 logicalOperator: 'or',
625609 }
626610 : valueSchemas[0]!;
611611+612612+ // Check if any $ref schemas in schemaItems have this discriminator property
613613+ // If yes, mark them to omit it to avoid conflicts
614614+ for (const item of schemaItems) {
615615+ if (item.$ref || item.symbolRef) {
616616+ // Check if the referenced schema has this property
617617+ const hasProperty = (() => {
618618+ if (!item.$ref) return false;
619619+ try {
620620+ const refSchema = context.resolveRef<SchemaObject>(item.$ref);
621621+ // Check if the discriminator property exists in the ref schema
622622+ return (
623623+ refSchema.properties?.[discriminator.propertyName] !==
624624+ undefined ||
625625+ (refSchema.allOf &&
626626+ refSchema.allOf.some((allOfItem) => {
627627+ const resolved = allOfItem.$ref
628628+ ? context.resolveRef<SchemaObject>(allOfItem.$ref)
629629+ : allOfItem;
630630+ return (
631631+ resolved.properties?.[discriminator.propertyName] !==
632632+ undefined
633633+ );
634634+ }))
635635+ );
636636+ } catch {
637637+ return false;
638638+ }
639639+ })();
640640+641641+ if (hasProperty) {
642642+ // Mark this ref to omit the discriminator property
643643+ if (!item.omit) {
644644+ item.omit = [discriminator.propertyName];
645645+ } else if (!item.omit.includes(discriminator.propertyName)) {
646646+ item.omit = [...item.omit, discriminator.propertyName];
647647+ }
648648+ }
649649+ }
650650+ }
627651628652 // Find the inline schema (non-$ref) to merge the discriminator property into
629653 // The inline schema should be the last non-$ref item in schemaItems