Skip to content

Commit

Permalink
Revise creation of composite union/intersection type predicates
Browse files Browse the repository at this point in the history
  • Loading branch information
ahejlsberg committed May 7, 2023
1 parent 42d69cf commit a54709c
Showing 1 changed file with 13 additions and 18 deletions.
31 changes: 13 additions & 18 deletions src/compiler/checker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16531,36 +16531,31 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
}

function getUnionOrIntersectionTypePredicate(signatures: readonly Signature[], kind: TypeFlags | undefined): TypePredicate | undefined {
let first: TypePredicate | undefined;
let last: TypePredicate | undefined;
const types: Type[] = [];
for (const sig of signatures) {
const pred = getTypePredicateOfSignature(sig);
if (!pred || pred.kind === TypePredicateKind.AssertsThis || pred.kind === TypePredicateKind.AssertsIdentifier) {
if (kind !== TypeFlags.Intersection) {
continue;
}
else {
return; // intersections demand all members be type predicates for the result to have a predicate
}
}

if (first) {
if (!typePredicateKindsMatch(first, pred)) {
// No common type predicate.
if (pred) {
// Constituent type predicates must all have matching kinds. We don't create composite type predicates for assertions.
if (pred.kind !== TypePredicateKind.This && pred.kind !== TypePredicateKind.Identifier || last && !typePredicateKindsMatch(last, pred)) {
return undefined;
}
last = pred;
types.push(pred.type);
}
else {
first = pred;
// In composite union signatures we permit and ignore signatures with a return type `false`.
const returnType = kind !== TypeFlags.Intersection ? getReturnTypeOfSignature(sig) : undefined;
if (returnType !== falseType && returnType !== regularFalseType) {
return undefined;
}
}
types.push(pred.type);
}
if (!first) {
// No signatures had a type predicate.
if (!last) {
return undefined;
}
const compositeType = getUnionOrIntersectionType(types, kind);
return createTypePredicate(first.kind, first.parameterName, first.parameterIndex, compositeType);
return createTypePredicate(last.kind, last.parameterName, last.parameterIndex, compositeType);
}

function typePredicateKindsMatch(a: TypePredicate, b: TypePredicate): boolean {
Expand Down

0 comments on commit a54709c

Please sign in to comment.