mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-05-19 01:33:15 -05:00
Fix creation of composite union type predicates (#54169)
This commit is contained in:
@@ -16515,36 +16515,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 (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);
|
||||
}
|
||||
|
||||
if (first) {
|
||||
if (!typePredicateKindsMatch(first, pred)) {
|
||||
// No common type predicate.
|
||||
else {
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
else {
|
||||
first = pred;
|
||||
}
|
||||
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 {
|
||||
|
||||
Reference in New Issue
Block a user