File tree Expand file tree Collapse file tree 2 files changed +38
-0
lines changed Expand file tree Collapse file tree 2 files changed +38
-0
lines changed Original file line number Diff line number Diff line change @@ -4,6 +4,7 @@ import { SubTypeFormatter } from "../SubTypeFormatter";
44import { BaseType } from "../Type/BaseType" ;
55import { UnionType } from "../Type/UnionType" ;
66import { TypeFormatter } from "../TypeFormatter" ;
7+ import { mergeDefinitions } from "../Utils/mergeDefinitions" ;
78import { uniqueArray } from "../Utils/uniqueArray" ;
89
910export class UnionTypeFormatter implements SubTypeFormatter {
@@ -45,6 +46,18 @@ export class UnionTypeFormatter implements SubTypeFormatter {
4546 }
4647 }
4748
49+ for ( let idx = 0 ; idx < flattenedDefinitions . length - 1 ; idx ++ ) {
50+ for ( let comp = idx + 1 ; comp < flattenedDefinitions . length ; ) {
51+ const merged = mergeDefinitions ( flattenedDefinitions [ idx ] , flattenedDefinitions [ comp ] ) ;
52+ if ( merged ) {
53+ flattenedDefinitions [ idx ] = merged ;
54+ flattenedDefinitions . splice ( comp , 1 ) ;
55+ } else {
56+ comp ++ ;
57+ }
58+ }
59+ }
60+
4861 return flattenedDefinitions . length > 1
4962 ? {
5063 anyOf : flattenedDefinitions ,
Original file line number Diff line number Diff line change 1+ import { Definition } from "../Schema/Definition" ;
2+ import { uniqueArray } from "./uniqueArray" ;
3+
4+ /**
5+ * Attempt to merge two disjoint definitions into one. Definitions are disjoint
6+ * (and therefore mergeable) if all of the following are true:
7+ * 1) Each has a 'type' property, and they share no types in common,
8+ * 2) The cross-type validation properties 'enum' and 'const' are not on either definition, and
9+ * 3) The two definitions have no properties besides 'type' in common.
10+ *
11+ * Returns the merged definition, or null if the two defs were not disjoint.
12+ */
13+ export function mergeDefinitions ( def1 : Definition , def2 : Definition ) : Definition | null {
14+ const { type : type1 , ...props1 } = def1 ;
15+ const { type : type2 , ...props2 } = def2 ;
16+ const types = [ type1 ! , type2 ! ] . flat ( ) ;
17+ if ( ! type1 || ! type2 || uniqueArray ( types ) . length !== types . length ) {
18+ return null ;
19+ }
20+ const keys = [ Object . keys ( props1 ) , Object . keys ( props2 ) ] . flat ( ) ;
21+ if ( keys . includes ( "enum" ) || keys . includes ( "const" ) || uniqueArray ( keys ) . length !== keys . length ) {
22+ return null ;
23+ }
24+ return { type : types , ...props1 , ...props2 } ;
25+ }
You can’t perform that action at this time.
0 commit comments