11import _ from 'lodash' ;
22import { Node , TypeNode } from './node' ;
33import { isLiteralNode } from './literal' ;
4- import { isIntrinsicNode } from './intrinsic' ;
4+ import { intrinsicNode , isIntrinsicNode } from './intrinsic' ;
55import { isReferenceNode } from './reference' ;
66import { isInterfaceNode } from './interface' ;
77
@@ -16,6 +16,7 @@ export function unionNode(types: TypeNode[]): UnionNode {
1616 const flatTypes : TypeNode [ ] = [ ] ;
1717
1818 flattenTypes ( types ) ;
19+ sanitizeBooleanLiterals ( flatTypes ) ;
1920
2021 function flattenTypes ( nodes : TypeNode [ ] ) {
2122 nodes . forEach ( ( x ) => {
@@ -37,7 +38,9 @@ export function isUnionNode(node: Node): node is UnionNode {
3738 return node . nodeType === typeString ;
3839}
3940
40- export function uniqueUnionTypes ( node : UnionNode ) : UnionNode {
41+ function uniqueUnionTypes ( node : UnionNode ) : UnionNode {
42+ // Typescript parses foo?: boolean as a union of `true | false | undefined`.
43+ // We want to simplify this to just `boolean | undefined`.
4144 return {
4245 nodeType : node . nodeType ,
4346 types : _ . uniqBy ( node . types , ( x ) => {
@@ -61,3 +64,19 @@ export function uniqueUnionTypes(node: UnionNode): UnionNode {
6164 } ) ,
6265 } ;
6366}
67+
68+ function sanitizeBooleanLiterals ( members : TypeNode [ ] ) : void {
69+ const trueLiteralIndex = members . findIndex ( ( x ) => isLiteralNode ( x ) && x . value === 'true' ) ;
70+ const falseLiteralIndex = members . findIndex ( ( x ) => isLiteralNode ( x ) && x . value === 'false' ) ;
71+
72+ if ( trueLiteralIndex !== - 1 && falseLiteralIndex !== - 1 ) {
73+ const booleanNode = intrinsicNode ( 'boolean' ) ;
74+ if ( trueLiteralIndex > falseLiteralIndex ) {
75+ members . splice ( trueLiteralIndex , 1 ) ;
76+ members . splice ( falseLiteralIndex , 1 , booleanNode ) ;
77+ } else {
78+ members . splice ( falseLiteralIndex , 1 ) ;
79+ members . splice ( trueLiteralIndex , 1 , booleanNode ) ;
80+ }
81+ }
82+ }
0 commit comments