Skip to content

Commit 1ac1528

Browse files
committed
Make type guard function types invariant in the type guarded for.
Fix one break in the compiler, and add a workaround to test case thisPredicateFunctionQuickInfo01, which used a code pattern that no longer works. Fixes microsoft#26981.
1 parent 07966dc commit 1ac1528

9 files changed

+264
-224
lines changed

src/compiler/checker.ts

+12-7
Original file line numberDiff line numberDiff line change
@@ -10920,7 +10920,7 @@ namespace ts {
1092010920
target: Signature,
1092110921
ignoreReturnTypes: boolean): boolean {
1092210922
return compareSignaturesRelated(source, target, CallbackCheck.None, ignoreReturnTypes, /*reportErrors*/ false,
10923-
/*errorReporter*/ undefined, compareTypesAssignable) !== Ternary.False;
10923+
/*errorReporter*/ undefined, compareTypesAssignable, compareTypesIdentical) !== Ternary.False;
1092410924
}
1092510925

1092610926
type ErrorReporter = (message: DiagnosticMessage, arg0?: string, arg1?: string) => void;
@@ -10934,7 +10934,8 @@ namespace ts {
1093410934
ignoreReturnTypes: boolean,
1093510935
reportErrors: boolean,
1093610936
errorReporter: ErrorReporter | undefined,
10937-
compareTypes: TypeComparer): Ternary {
10937+
compareTypes: TypeComparer,
10938+
localCompareTypesIdentical: TypeComparer): Ternary {
1093810939
// TODO (drosen): De-duplicate code between related functions.
1093910940
if (source === target) {
1094010941
return Ternary.True;
@@ -11000,7 +11001,7 @@ namespace ts {
1100011001
(getFalsyFlags(sourceType) & TypeFlags.Nullable) === (getFalsyFlags(targetType) & TypeFlags.Nullable);
1100111002
const related = callbacks ?
1100211003
// TODO: GH#18217 It will work if they're both `undefined`, but not if only one is
11003-
compareSignaturesRelated(targetSig!, sourceSig!, strictVariance ? CallbackCheck.Strict : CallbackCheck.Bivariant, /*ignoreReturnTypes*/ false, reportErrors, errorReporter, compareTypes) :
11004+
compareSignaturesRelated(targetSig!, sourceSig!, strictVariance ? CallbackCheck.Strict : CallbackCheck.Bivariant, /*ignoreReturnTypes*/ false, reportErrors, errorReporter, compareTypes, localCompareTypesIdentical) :
1100411005
!callbackCheck && !strictVariance && compareTypes(sourceType, targetType, /*reportErrors*/ false) || compareTypes(targetType, sourceType, reportErrors);
1100511006
if (!related) {
1100611007
if (reportErrors) {
@@ -11027,7 +11028,7 @@ namespace ts {
1102711028
if (targetTypePredicate) {
1102811029
const sourceTypePredicate = getTypePredicateOfSignature(source);
1102911030
if (sourceTypePredicate) {
11030-
result &= compareTypePredicateRelatedTo(sourceTypePredicate, targetTypePredicate, source.declaration!, target.declaration!, reportErrors, errorReporter, compareTypes); // TODO: GH#18217
11031+
result &= compareTypePredicateRelatedTo(sourceTypePredicate, targetTypePredicate, source.declaration!, target.declaration!, reportErrors, errorReporter, localCompareTypesIdentical); // TODO: GH#18217
1103111032
}
1103211033
else if (isIdentifierTypePredicate(targetTypePredicate)) {
1103311034
if (reportErrors) {
@@ -11056,7 +11057,7 @@ namespace ts {
1105611057
targetDeclaration: SignatureDeclaration | JSDocSignature,
1105711058
reportErrors: boolean,
1105811059
errorReporter: ErrorReporter | undefined,
11059-
compareTypes: (s: Type, t: Type, reportErrors?: boolean) => Ternary): Ternary {
11060+
localCompareTypesIdentical: (s: Type, t: Type, reportErrors?: boolean) => Ternary): Ternary {
1106011061
if (source.kind !== target.kind) {
1106111062
if (reportErrors) {
1106211063
errorReporter!(Diagnostics.A_this_based_type_guard_is_not_compatible_with_a_parameter_based_type_guard);
@@ -11078,7 +11079,7 @@ namespace ts {
1107811079
}
1107911080
}
1108011081

11081-
const related = compareTypes(source.type, target.type, reportErrors);
11082+
const related = localCompareTypesIdentical(source.type, target.type, reportErrors);
1108211083
if (related === Ternary.False && reportErrors) {
1108311084
errorReporter!(Diagnostics.Type_predicate_0_is_not_assignable_to_1, typePredicateToString(source), typePredicateToString(target));
1108411085
}
@@ -12355,7 +12356,11 @@ namespace ts {
1235512356
*/
1235612357
function signatureRelatedTo(source: Signature, target: Signature, erase: boolean, reportErrors: boolean): Ternary {
1235712358
return compareSignaturesRelated(erase ? getErasedSignature(source) : source, erase ? getErasedSignature(target) : target,
12358-
CallbackCheck.None, /*ignoreReturnTypes*/ false, reportErrors, reportError, isRelatedTo);
12359+
CallbackCheck.None, /*ignoreReturnTypes*/ false, reportErrors, reportError, isRelatedTo,
12360+
// If we are already in an identity check, we need to use isRelatedTo to use the
12361+
// existing recursion limiter rather than start a new one, which could allow us
12362+
// to recurse infinitely through this code path.
12363+
relation === identityRelation ? isRelatedTo : compareTypesIdentical);
1235912364
}
1236012365

1236112366
function signaturesIdenticalTo(source: Type, target: Type, kind: SignatureKind): Ternary {

src/services/documentHighlights.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ namespace ts.DocumentHighlights {
7575
case SyntaxKind.SetKeyword:
7676
return getFromAllDeclarations(isAccessor, [SyntaxKind.GetKeyword, SyntaxKind.SetKeyword]);
7777
case SyntaxKind.AwaitKeyword:
78-
return useParent(node.parent, isAwaitExpression, getAsyncAndAwaitOccurrences);
78+
return useParent<AwaitExpression>(node.parent, isAwaitExpression, getAsyncAndAwaitOccurrences);
7979
case SyntaxKind.AsyncKeyword:
8080
return highlightSpans(getAsyncAndAwaitOccurrences(node));
8181
case SyntaxKind.YieldKeyword:

0 commit comments

Comments
 (0)