Skip to content

Commit a54709c

Browse files
committed
Revise creation of composite union/intersection type predicates
1 parent 42d69cf commit a54709c

File tree

1 file changed

+13
-18
lines changed

1 file changed

+13
-18
lines changed

src/compiler/checker.ts

+13-18
Original file line numberDiff line numberDiff line change
@@ -16531,36 +16531,31 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
1653116531
}
1653216532

1653316533
function getUnionOrIntersectionTypePredicate(signatures: readonly Signature[], kind: TypeFlags | undefined): TypePredicate | undefined {
16534-
let first: TypePredicate | undefined;
16534+
let last: TypePredicate | undefined;
1653516535
const types: Type[] = [];
1653616536
for (const sig of signatures) {
1653716537
const pred = getTypePredicateOfSignature(sig);
16538-
if (!pred || pred.kind === TypePredicateKind.AssertsThis || pred.kind === TypePredicateKind.AssertsIdentifier) {
16539-
if (kind !== TypeFlags.Intersection) {
16540-
continue;
16541-
}
16542-
else {
16543-
return; // intersections demand all members be type predicates for the result to have a predicate
16544-
}
16545-
}
16546-
16547-
if (first) {
16548-
if (!typePredicateKindsMatch(first, pred)) {
16549-
// No common type predicate.
16538+
if (pred) {
16539+
// Constituent type predicates must all have matching kinds. We don't create composite type predicates for assertions.
16540+
if (pred.kind !== TypePredicateKind.This && pred.kind !== TypePredicateKind.Identifier || last && !typePredicateKindsMatch(last, pred)) {
1655016541
return undefined;
1655116542
}
16543+
last = pred;
16544+
types.push(pred.type);
1655216545
}
1655316546
else {
16554-
first = pred;
16547+
// In composite union signatures we permit and ignore signatures with a return type `false`.
16548+
const returnType = kind !== TypeFlags.Intersection ? getReturnTypeOfSignature(sig) : undefined;
16549+
if (returnType !== falseType && returnType !== regularFalseType) {
16550+
return undefined;
16551+
}
1655516552
}
16556-
types.push(pred.type);
1655716553
}
16558-
if (!first) {
16559-
// No signatures had a type predicate.
16554+
if (!last) {
1656016555
return undefined;
1656116556
}
1656216557
const compositeType = getUnionOrIntersectionType(types, kind);
16563-
return createTypePredicate(first.kind, first.parameterName, first.parameterIndex, compositeType);
16558+
return createTypePredicate(last.kind, last.parameterName, last.parameterIndex, compositeType);
1656416559
}
1656516560

1656616561
function typePredicateKindsMatch(a: TypePredicate, b: TypePredicate): boolean {

0 commit comments

Comments
 (0)