@@ -2,15 +2,7 @@ import * as ts from "typescript";
22import { TransformationContext } from "../../context" ;
33
44export function isTypeWithFlags ( context : TransformationContext , type : ts . Type , flags : ts . TypeFlags ) : boolean {
5- const predicate = ( type : ts . Type ) => {
6- if ( type . symbol ) {
7- const baseConstraint = context . checker . getBaseConstraintOfType ( type ) ;
8- if ( baseConstraint && baseConstraint !== type ) {
9- return isTypeWithFlags ( context , baseConstraint , flags ) ;
10- }
11- }
12- return ( type . flags & flags ) !== 0 ;
13- } ;
5+ const predicate = ( type : ts . Type ) => ( type . flags & flags ) !== 0 ;
146
157 return typeAlwaysSatisfies ( context , type , predicate ) ;
168}
@@ -20,6 +12,11 @@ export function typeAlwaysSatisfies(
2012 type : ts . Type ,
2113 predicate : ( type : ts . Type ) => boolean
2214) : boolean {
15+ const baseConstraint = context . checker . getBaseConstraintOfType ( type ) ;
16+ if ( baseConstraint ) {
17+ type = baseConstraint ;
18+ }
19+
2320 if ( predicate ( type ) ) {
2421 return true ;
2522 }
@@ -40,6 +37,14 @@ export function typeCanSatisfy(
4037 type : ts . Type ,
4138 predicate : ( type : ts . Type ) => boolean
4239) : boolean {
40+ const baseConstraint = context . checker . getBaseConstraintOfType ( type ) ;
41+ if ( ! baseConstraint ) {
42+ // type parameter with no constraint can be anything, assume it might satisfy predicate
43+ if ( type . isTypeParameter ( ) ) return true ;
44+ } else {
45+ type = baseConstraint ;
46+ }
47+
4348 if ( predicate ( type ) ) {
4449 return true ;
4550 }
@@ -110,3 +115,32 @@ export function isArrayType(context: TransformationContext, type: ts.Type): bool
110115export function isFunctionType ( type : ts . Type ) : boolean {
111116 return type . getCallSignatures ( ) . length > 0 ;
112117}
118+
119+ export function canBeFalsy ( context : TransformationContext , type : ts . Type ) : boolean {
120+ const strictNullChecks = context . options . strict === true || context . options . strictNullChecks === true ;
121+ const falsyFlags =
122+ ts . TypeFlags . Boolean |
123+ ts . TypeFlags . BooleanLiteral |
124+ ts . TypeFlags . Never |
125+ ts . TypeFlags . Void |
126+ ts . TypeFlags . Unknown |
127+ ts . TypeFlags . Any |
128+ ts . TypeFlags . Undefined |
129+ ts . TypeFlags . Null ;
130+ return typeCanSatisfy (
131+ context ,
132+ type ,
133+ type => ( type . flags & falsyFlags ) !== 0 || ( ! strictNullChecks && ! type . isLiteral ( ) )
134+ ) ;
135+ }
136+
137+ export function canBeFalsyWhenNotNull ( context : TransformationContext , type : ts . Type ) : boolean {
138+ const falsyFlags =
139+ ts . TypeFlags . Boolean |
140+ ts . TypeFlags . BooleanLiteral |
141+ ts . TypeFlags . Never |
142+ ts . TypeFlags . Void |
143+ ts . TypeFlags . Unknown |
144+ ts . TypeFlags . Any ;
145+ return typeCanSatisfy ( context , type , type => ( type . flags & falsyFlags ) !== 0 ) ;
146+ }
0 commit comments