Skip to content

Commit af70f24

Browse files
authored
Always resetErrorInfo if structuredTypeRelatedTo succeeds (#49718)
1 parent 8002369 commit af70f24

5 files changed

Lines changed: 121 additions & 17 deletions

File tree

src/compiler/checker.ts

Lines changed: 9 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -19368,13 +19368,21 @@ m2: ${(this.mapper2 as unknown as DebugTypeMapper).__debugToString().split("\n")
1936819368
}
1936919369

1937019370
function structuredTypeRelatedTo(source: Type, target: Type, reportErrors: boolean, intersectionState: IntersectionState): Ternary {
19371+
const saveErrorInfo = captureErrorCalculationState();
19372+
const result = structuredTypeRelatedToWorker(source, target, reportErrors, intersectionState, saveErrorInfo);
19373+
if (result) {
19374+
resetErrorInfo(saveErrorInfo);
19375+
}
19376+
return result;
19377+
}
19378+
19379+
function structuredTypeRelatedToWorker(source: Type, target: Type, reportErrors: boolean, intersectionState: IntersectionState, saveErrorInfo: ReturnType<typeof captureErrorCalculationState>): Ternary {
1937119380
if (intersectionState & IntersectionState.PropertyCheck) {
1937219381
return propertiesRelatedTo(source, target, reportErrors, /*excludedProperties*/ undefined, IntersectionState.None);
1937319382
}
1937419383
let result: Ternary;
1937519384
let originalErrorInfo: DiagnosticMessageChain | undefined;
1937619385
let varianceCheckFailed = false;
19377-
const saveErrorInfo = captureErrorCalculationState();
1937819386
let sourceFlags = source.flags;
1937919387
const targetFlags = target.flags;
1938019388
if (relation === identityRelation) {
@@ -19438,7 +19446,6 @@ m2: ${(this.mapper2 as unknown as DebugTypeMapper).__debugToString().split("\n")
1943819446
if (constraint && everyType(constraint, c => c !== source)) { // Skip comparison if expansion contains the source itself
1943919447
// TODO: Stack errors so we get a pyramid for the "normal" comparison above, _and_ a second for this
1944019448
if (result = isRelatedTo(constraint, target, RecursionFlags.Source, /*reportErrors*/ false, /*headMessage*/ undefined, intersectionState)) {
19441-
resetErrorInfo(saveErrorInfo);
1944219449
return result;
1944319450
}
1944419451
}
@@ -19572,7 +19579,6 @@ m2: ${(this.mapper2 as unknown as DebugTypeMapper).__debugToString().split("\n")
1957219579
result &= isRelatedTo((source as IndexedAccessType).indexType, (target as IndexedAccessType).indexType, RecursionFlags.Both, reportErrors);
1957319580
}
1957419581
if (result) {
19575-
resetErrorInfo(saveErrorInfo);
1957619582
return result;
1957719583
}
1957819584
if (reportErrors) {
@@ -19677,7 +19683,6 @@ m2: ${(this.mapper2 as unknown as DebugTypeMapper).__debugToString().split("\n")
1967719683
// If we reach 10 levels of nesting for the same conditional type, assume it is an infinitely expanding recursive
1967819684
// conditional type and bail out with a Ternary.Maybe result.
1967919685
if (isDeeplyNestedType(target, targetStack, targetDepth, 10)) {
19680-
resetErrorInfo(saveErrorInfo);
1968119686
return Ternary.Maybe;
1968219687
}
1968319688
const c = target as ConditionalType;
@@ -19692,7 +19697,6 @@ m2: ${(this.mapper2 as unknown as DebugTypeMapper).__debugToString().split("\n")
1969219697
if (result = skipTrue ? Ternary.True : isRelatedTo(source, getTrueTypeFromConditionalType(c), RecursionFlags.Target, /*reportErrors*/ false)) {
1969319698
result &= skipFalse ? Ternary.True : isRelatedTo(source, getFalseTypeFromConditionalType(c), RecursionFlags.Target, /*reportErrors*/ false);
1969419699
if (result) {
19695-
resetErrorInfo(saveErrorInfo);
1969619700
return result;
1969719701
}
1969819702
}
@@ -19725,12 +19729,10 @@ m2: ${(this.mapper2 as unknown as DebugTypeMapper).__debugToString().split("\n")
1972519729
const constraint = getConstraintOfType(source as TypeVariable) || unknownType;
1972619730
// hi-speed no-this-instantiation check (less accurate, but avoids costly `this`-instantiation when the constraint will suffice), see #28231 for report on why this is needed
1972719731
if (result = isRelatedTo(constraint, target, RecursionFlags.Source, /*reportErrors*/ false, /*headMessage*/ undefined, intersectionState)) {
19728-
resetErrorInfo(saveErrorInfo);
1972919732
return result;
1973019733
}
1973119734
// slower, fuller, this-instantiated check (necessary when comparing raw `this` types from base classes), see `subclassWithPolymorphicThisIsAssignable.ts` test for example
1973219735
else if (result = isRelatedTo(getTypeWithThisArgument(constraint, source), target, RecursionFlags.Source, reportErrors && constraint !== unknownType && !(targetFlags & sourceFlags & TypeFlags.TypeParameter), /*headMessage*/ undefined, intersectionState)) {
19733-
resetErrorInfo(saveErrorInfo);
1973419736
return result;
1973519737
}
1973619738
if (isMappedTypeGenericIndexedAccess(source)) {
@@ -19739,7 +19741,6 @@ m2: ${(this.mapper2 as unknown as DebugTypeMapper).__debugToString().split("\n")
1973919741
const indexConstraint = getConstraintOfType((source as IndexedAccessType).indexType);
1974019742
if (indexConstraint) {
1974119743
if (result = isRelatedTo(getIndexedAccessType((source as IndexedAccessType).objectType, indexConstraint), target, RecursionFlags.Source, reportErrors)) {
19742-
resetErrorInfo(saveErrorInfo);
1974319744
return result;
1974419745
}
1974519746
}
@@ -19748,15 +19749,13 @@ m2: ${(this.mapper2 as unknown as DebugTypeMapper).__debugToString().split("\n")
1974819749
}
1974919750
else if (sourceFlags & TypeFlags.Index) {
1975019751
if (result = isRelatedTo(keyofConstraintType, target, RecursionFlags.Source, reportErrors)) {
19751-
resetErrorInfo(saveErrorInfo);
1975219752
return result;
1975319753
}
1975419754
}
1975519755
else if (sourceFlags & TypeFlags.TemplateLiteral && !(targetFlags & TypeFlags.Object)) {
1975619756
if (!(targetFlags & TypeFlags.TemplateLiteral)) {
1975719757
const constraint = getBaseConstraintOfType(source);
1975819758
if (constraint && constraint !== source && (result = isRelatedTo(constraint, target, RecursionFlags.Source, reportErrors))) {
19759-
resetErrorInfo(saveErrorInfo);
1976019759
return result;
1976119760
}
1976219761
}
@@ -19767,14 +19766,12 @@ m2: ${(this.mapper2 as unknown as DebugTypeMapper).__debugToString().split("\n")
1976719766
return Ternary.False;
1976819767
}
1976919768
if (result = isRelatedTo((source as StringMappingType).type, (target as StringMappingType).type, RecursionFlags.Both, reportErrors)) {
19770-
resetErrorInfo(saveErrorInfo);
1977119769
return result;
1977219770
}
1977319771
}
1977419772
else {
1977519773
const constraint = getBaseConstraintOfType(source);
1977619774
if (constraint && (result = isRelatedTo(constraint, target, RecursionFlags.Source, reportErrors))) {
19777-
resetErrorInfo(saveErrorInfo);
1977819775
return result;
1977919776
}
1978019777
}
@@ -19783,7 +19780,6 @@ m2: ${(this.mapper2 as unknown as DebugTypeMapper).__debugToString().split("\n")
1978319780
// If we reach 10 levels of nesting for the same conditional type, assume it is an infinitely expanding recursive
1978419781
// conditional type and bail out with a Ternary.Maybe result.
1978519782
if (isDeeplyNestedType(source, sourceStack, sourceDepth, 10)) {
19786-
resetErrorInfo(saveErrorInfo);
1978719783
return Ternary.Maybe;
1978819784
}
1978919785
if (targetFlags & TypeFlags.Conditional) {
@@ -19806,7 +19802,6 @@ m2: ${(this.mapper2 as unknown as DebugTypeMapper).__debugToString().split("\n")
1980619802
result &= isRelatedTo(getFalseTypeFromConditionalType(source as ConditionalType), getFalseTypeFromConditionalType(target as ConditionalType), RecursionFlags.Both, reportErrors);
1980719803
}
1980819804
if (result) {
19809-
resetErrorInfo(saveErrorInfo);
1981019805
return result;
1981119806
}
1981219807
}
@@ -19817,7 +19812,6 @@ m2: ${(this.mapper2 as unknown as DebugTypeMapper).__debugToString().split("\n")
1981719812
const distributiveConstraint = hasNonCircularBaseConstraint(source) ? getConstraintOfDistributiveConditionalType(source as ConditionalType) : undefined;
1981819813
if (distributiveConstraint) {
1981919814
if (result = isRelatedTo(distributiveConstraint, target, RecursionFlags.Source, reportErrors)) {
19820-
resetErrorInfo(saveErrorInfo);
1982119815
return result;
1982219816
}
1982319817
}
@@ -19828,7 +19822,6 @@ m2: ${(this.mapper2 as unknown as DebugTypeMapper).__debugToString().split("\n")
1982819822
const defaultConstraint = getDefaultConstraintOfConditionalType(source as ConditionalType);
1982919823
if (defaultConstraint) {
1983019824
if (result = isRelatedTo(defaultConstraint, target, RecursionFlags.Source, reportErrors)) {
19831-
resetErrorInfo(saveErrorInfo);
1983219825
return result;
1983319826
}
1983419827
}
@@ -19841,7 +19834,6 @@ m2: ${(this.mapper2 as unknown as DebugTypeMapper).__debugToString().split("\n")
1984119834
if (isGenericMappedType(target)) {
1984219835
if (isGenericMappedType(source)) {
1984319836
if (result = mappedTypeRelatedTo(source, target, reportErrors)) {
19844-
resetErrorInfo(saveErrorInfo);
1984519837
return result;
1984619838
}
1984719839
}
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
//// [relatedViaDiscriminatedTypeNoError.ts]
2+
class Model {
3+
constructor(public flag: boolean) {}
4+
}
5+
6+
type DiscriminatedUnion = { flag: true } | { flag: false };
7+
class A<T extends DiscriminatedUnion> {
8+
constructor(public model: T) { }
9+
}
10+
11+
class B extends A<Model> { }
12+
13+
14+
//// [relatedViaDiscriminatedTypeNoError.js]
15+
var __extends = (this && this.__extends) || (function () {
16+
var extendStatics = function (d, b) {
17+
extendStatics = Object.setPrototypeOf ||
18+
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
19+
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
20+
return extendStatics(d, b);
21+
};
22+
return function (d, b) {
23+
if (typeof b !== "function" && b !== null)
24+
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
25+
extendStatics(d, b);
26+
function __() { this.constructor = d; }
27+
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
28+
};
29+
})();
30+
var Model = /** @class */ (function () {
31+
function Model(flag) {
32+
this.flag = flag;
33+
}
34+
return Model;
35+
}());
36+
var A = /** @class */ (function () {
37+
function A(model) {
38+
this.model = model;
39+
}
40+
return A;
41+
}());
42+
var B = /** @class */ (function (_super) {
43+
__extends(B, _super);
44+
function B() {
45+
return _super !== null && _super.apply(this, arguments) || this;
46+
}
47+
return B;
48+
}(A));
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
=== tests/cases/compiler/relatedViaDiscriminatedTypeNoError.ts ===
2+
class Model {
3+
>Model : Symbol(Model, Decl(relatedViaDiscriminatedTypeNoError.ts, 0, 0))
4+
5+
constructor(public flag: boolean) {}
6+
>flag : Symbol(Model.flag, Decl(relatedViaDiscriminatedTypeNoError.ts, 1, 16))
7+
}
8+
9+
type DiscriminatedUnion = { flag: true } | { flag: false };
10+
>DiscriminatedUnion : Symbol(DiscriminatedUnion, Decl(relatedViaDiscriminatedTypeNoError.ts, 2, 1))
11+
>flag : Symbol(flag, Decl(relatedViaDiscriminatedTypeNoError.ts, 4, 27))
12+
>flag : Symbol(flag, Decl(relatedViaDiscriminatedTypeNoError.ts, 4, 44))
13+
14+
class A<T extends DiscriminatedUnion> {
15+
>A : Symbol(A, Decl(relatedViaDiscriminatedTypeNoError.ts, 4, 59))
16+
>T : Symbol(T, Decl(relatedViaDiscriminatedTypeNoError.ts, 5, 8))
17+
>DiscriminatedUnion : Symbol(DiscriminatedUnion, Decl(relatedViaDiscriminatedTypeNoError.ts, 2, 1))
18+
19+
constructor(public model: T) { }
20+
>model : Symbol(A.model, Decl(relatedViaDiscriminatedTypeNoError.ts, 6, 16))
21+
>T : Symbol(T, Decl(relatedViaDiscriminatedTypeNoError.ts, 5, 8))
22+
}
23+
24+
class B extends A<Model> { }
25+
>B : Symbol(B, Decl(relatedViaDiscriminatedTypeNoError.ts, 7, 1))
26+
>A : Symbol(A, Decl(relatedViaDiscriminatedTypeNoError.ts, 4, 59))
27+
>Model : Symbol(Model, Decl(relatedViaDiscriminatedTypeNoError.ts, 0, 0))
28+
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
=== tests/cases/compiler/relatedViaDiscriminatedTypeNoError.ts ===
2+
class Model {
3+
>Model : Model
4+
5+
constructor(public flag: boolean) {}
6+
>flag : boolean
7+
}
8+
9+
type DiscriminatedUnion = { flag: true } | { flag: false };
10+
>DiscriminatedUnion : { flag: true; } | { flag: false; }
11+
>flag : true
12+
>true : true
13+
>flag : false
14+
>false : false
15+
16+
class A<T extends DiscriminatedUnion> {
17+
>A : A<T>
18+
19+
constructor(public model: T) { }
20+
>model : T
21+
}
22+
23+
class B extends A<Model> { }
24+
>B : B
25+
>A : A<Model>
26+
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
class Model {
2+
constructor(public flag: boolean) {}
3+
}
4+
5+
type DiscriminatedUnion = { flag: true } | { flag: false };
6+
class A<T extends DiscriminatedUnion> {
7+
constructor(public model: T) { }
8+
}
9+
10+
class B extends A<Model> { }

0 commit comments

Comments
 (0)