diff --git a/src/nodes/Conditional.ts b/src/nodes/Conditional.ts index fe8c4ebfc..4612b1c7c 100644 --- a/src/nodes/Conditional.ts +++ b/src/nodes/Conditional.ts @@ -188,16 +188,20 @@ export default class Conditional extends Expression { context ); + // The condition did some guarding if the intersection of the revised and current sets is smaller than the current set + const guarded = + current.intersection(revisedTypes, context).size() < current.size(); + // Evaluate the yes branch with the revised types. if (this.yes instanceof Expression) this.yes.evaluateTypeSet(bind, original, revisedTypes, context); - // Evaluate the no branch with the complement of the revised types. + // Evaluate the no branch with the complement of the revised types, unless they weren't guarded, in which case we pass through the current types. if (this.no instanceof Expression) { this.no.evaluateTypeSet( bind, original, - current.difference(revisedTypes, context), + guarded ? current.difference(revisedTypes, context) : current, context ); } diff --git a/src/nodes/Expression.ts b/src/nodes/Expression.ts index 73ebffa2e..bac50644d 100644 --- a/src/nodes/Expression.ts +++ b/src/nodes/Expression.ts @@ -70,7 +70,7 @@ export default abstract class Expression extends Node { } /** - * Used to determine what types are possible for a given after evalutaing this expression/ + * Used to determine what types are possible for a given after evaluating this expression, implementing type guards. * Most expressions do not manipulate possible types at all; primarily is just logical operators and type checks. * */ abstract evaluateTypeSet(