Always resetErrorInfo if structuredTypeRelatedTo succeeds (#49718)

This commit is contained in:
Jake Bailey
2022-07-06 12:57:01 -07:00
committed by GitHub
parent 8002369871
commit af70f240a1
5 changed files with 121 additions and 17 deletions
+9 -17
View File
@@ -19368,13 +19368,21 @@ m2: ${(this.mapper2 as unknown as DebugTypeMapper).__debugToString().split("\n")
}
function structuredTypeRelatedTo(source: Type, target: Type, reportErrors: boolean, intersectionState: IntersectionState): Ternary {
const saveErrorInfo = captureErrorCalculationState();
const result = structuredTypeRelatedToWorker(source, target, reportErrors, intersectionState, saveErrorInfo);
if (result) {
resetErrorInfo(saveErrorInfo);
}
return result;
}
function structuredTypeRelatedToWorker(source: Type, target: Type, reportErrors: boolean, intersectionState: IntersectionState, saveErrorInfo: ReturnType<typeof captureErrorCalculationState>): Ternary {
if (intersectionState & IntersectionState.PropertyCheck) {
return propertiesRelatedTo(source, target, reportErrors, /*excludedProperties*/ undefined, IntersectionState.None);
}
let result: Ternary;
let originalErrorInfo: DiagnosticMessageChain | undefined;
let varianceCheckFailed = false;
const saveErrorInfo = captureErrorCalculationState();
let sourceFlags = source.flags;
const targetFlags = target.flags;
if (relation === identityRelation) {
@@ -19438,7 +19446,6 @@ m2: ${(this.mapper2 as unknown as DebugTypeMapper).__debugToString().split("\n")
if (constraint && everyType(constraint, c => c !== source)) { // Skip comparison if expansion contains the source itself
// TODO: Stack errors so we get a pyramid for the "normal" comparison above, _and_ a second for this
if (result = isRelatedTo(constraint, target, RecursionFlags.Source, /*reportErrors*/ false, /*headMessage*/ undefined, intersectionState)) {
resetErrorInfo(saveErrorInfo);
return result;
}
}
@@ -19572,7 +19579,6 @@ m2: ${(this.mapper2 as unknown as DebugTypeMapper).__debugToString().split("\n")
result &= isRelatedTo((source as IndexedAccessType).indexType, (target as IndexedAccessType).indexType, RecursionFlags.Both, reportErrors);
}
if (result) {
resetErrorInfo(saveErrorInfo);
return result;
}
if (reportErrors) {
@@ -19677,7 +19683,6 @@ m2: ${(this.mapper2 as unknown as DebugTypeMapper).__debugToString().split("\n")
// If we reach 10 levels of nesting for the same conditional type, assume it is an infinitely expanding recursive
// conditional type and bail out with a Ternary.Maybe result.
if (isDeeplyNestedType(target, targetStack, targetDepth, 10)) {
resetErrorInfo(saveErrorInfo);
return Ternary.Maybe;
}
const c = target as ConditionalType;
@@ -19692,7 +19697,6 @@ m2: ${(this.mapper2 as unknown as DebugTypeMapper).__debugToString().split("\n")
if (result = skipTrue ? Ternary.True : isRelatedTo(source, getTrueTypeFromConditionalType(c), RecursionFlags.Target, /*reportErrors*/ false)) {
result &= skipFalse ? Ternary.True : isRelatedTo(source, getFalseTypeFromConditionalType(c), RecursionFlags.Target, /*reportErrors*/ false);
if (result) {
resetErrorInfo(saveErrorInfo);
return result;
}
}
@@ -19725,12 +19729,10 @@ m2: ${(this.mapper2 as unknown as DebugTypeMapper).__debugToString().split("\n")
const constraint = getConstraintOfType(source as TypeVariable) || unknownType;
// 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
if (result = isRelatedTo(constraint, target, RecursionFlags.Source, /*reportErrors*/ false, /*headMessage*/ undefined, intersectionState)) {
resetErrorInfo(saveErrorInfo);
return result;
}
// slower, fuller, this-instantiated check (necessary when comparing raw `this` types from base classes), see `subclassWithPolymorphicThisIsAssignable.ts` test for example
else if (result = isRelatedTo(getTypeWithThisArgument(constraint, source), target, RecursionFlags.Source, reportErrors && constraint !== unknownType && !(targetFlags & sourceFlags & TypeFlags.TypeParameter), /*headMessage*/ undefined, intersectionState)) {
resetErrorInfo(saveErrorInfo);
return result;
}
if (isMappedTypeGenericIndexedAccess(source)) {
@@ -19739,7 +19741,6 @@ m2: ${(this.mapper2 as unknown as DebugTypeMapper).__debugToString().split("\n")
const indexConstraint = getConstraintOfType((source as IndexedAccessType).indexType);
if (indexConstraint) {
if (result = isRelatedTo(getIndexedAccessType((source as IndexedAccessType).objectType, indexConstraint), target, RecursionFlags.Source, reportErrors)) {
resetErrorInfo(saveErrorInfo);
return result;
}
}
@@ -19748,7 +19749,6 @@ m2: ${(this.mapper2 as unknown as DebugTypeMapper).__debugToString().split("\n")
}
else if (sourceFlags & TypeFlags.Index) {
if (result = isRelatedTo(keyofConstraintType, target, RecursionFlags.Source, reportErrors)) {
resetErrorInfo(saveErrorInfo);
return result;
}
}
@@ -19756,7 +19756,6 @@ m2: ${(this.mapper2 as unknown as DebugTypeMapper).__debugToString().split("\n")
if (!(targetFlags & TypeFlags.TemplateLiteral)) {
const constraint = getBaseConstraintOfType(source);
if (constraint && constraint !== source && (result = isRelatedTo(constraint, target, RecursionFlags.Source, reportErrors))) {
resetErrorInfo(saveErrorInfo);
return result;
}
}
@@ -19767,14 +19766,12 @@ m2: ${(this.mapper2 as unknown as DebugTypeMapper).__debugToString().split("\n")
return Ternary.False;
}
if (result = isRelatedTo((source as StringMappingType).type, (target as StringMappingType).type, RecursionFlags.Both, reportErrors)) {
resetErrorInfo(saveErrorInfo);
return result;
}
}
else {
const constraint = getBaseConstraintOfType(source);
if (constraint && (result = isRelatedTo(constraint, target, RecursionFlags.Source, reportErrors))) {
resetErrorInfo(saveErrorInfo);
return result;
}
}
@@ -19783,7 +19780,6 @@ m2: ${(this.mapper2 as unknown as DebugTypeMapper).__debugToString().split("\n")
// If we reach 10 levels of nesting for the same conditional type, assume it is an infinitely expanding recursive
// conditional type and bail out with a Ternary.Maybe result.
if (isDeeplyNestedType(source, sourceStack, sourceDepth, 10)) {
resetErrorInfo(saveErrorInfo);
return Ternary.Maybe;
}
if (targetFlags & TypeFlags.Conditional) {
@@ -19806,7 +19802,6 @@ m2: ${(this.mapper2 as unknown as DebugTypeMapper).__debugToString().split("\n")
result &= isRelatedTo(getFalseTypeFromConditionalType(source as ConditionalType), getFalseTypeFromConditionalType(target as ConditionalType), RecursionFlags.Both, reportErrors);
}
if (result) {
resetErrorInfo(saveErrorInfo);
return result;
}
}
@@ -19817,7 +19812,6 @@ m2: ${(this.mapper2 as unknown as DebugTypeMapper).__debugToString().split("\n")
const distributiveConstraint = hasNonCircularBaseConstraint(source) ? getConstraintOfDistributiveConditionalType(source as ConditionalType) : undefined;
if (distributiveConstraint) {
if (result = isRelatedTo(distributiveConstraint, target, RecursionFlags.Source, reportErrors)) {
resetErrorInfo(saveErrorInfo);
return result;
}
}
@@ -19828,7 +19822,6 @@ m2: ${(this.mapper2 as unknown as DebugTypeMapper).__debugToString().split("\n")
const defaultConstraint = getDefaultConstraintOfConditionalType(source as ConditionalType);
if (defaultConstraint) {
if (result = isRelatedTo(defaultConstraint, target, RecursionFlags.Source, reportErrors)) {
resetErrorInfo(saveErrorInfo);
return result;
}
}
@@ -19841,7 +19834,6 @@ m2: ${(this.mapper2 as unknown as DebugTypeMapper).__debugToString().split("\n")
if (isGenericMappedType(target)) {
if (isGenericMappedType(source)) {
if (result = mappedTypeRelatedTo(source, target, reportErrors)) {
resetErrorInfo(saveErrorInfo);
return result;
}
}
@@ -0,0 +1,48 @@
//// [relatedViaDiscriminatedTypeNoError.ts]
class Model {
constructor(public flag: boolean) {}
}
type DiscriminatedUnion = { flag: true } | { flag: false };
class A<T extends DiscriminatedUnion> {
constructor(public model: T) { }
}
class B extends A<Model> { }
//// [relatedViaDiscriminatedTypeNoError.js]
var __extends = (this && this.__extends) || (function () {
var extendStatics = function (d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
return extendStatics(d, b);
};
return function (d, b) {
if (typeof b !== "function" && b !== null)
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
var Model = /** @class */ (function () {
function Model(flag) {
this.flag = flag;
}
return Model;
}());
var A = /** @class */ (function () {
function A(model) {
this.model = model;
}
return A;
}());
var B = /** @class */ (function (_super) {
__extends(B, _super);
function B() {
return _super !== null && _super.apply(this, arguments) || this;
}
return B;
}(A));
@@ -0,0 +1,28 @@
=== tests/cases/compiler/relatedViaDiscriminatedTypeNoError.ts ===
class Model {
>Model : Symbol(Model, Decl(relatedViaDiscriminatedTypeNoError.ts, 0, 0))
constructor(public flag: boolean) {}
>flag : Symbol(Model.flag, Decl(relatedViaDiscriminatedTypeNoError.ts, 1, 16))
}
type DiscriminatedUnion = { flag: true } | { flag: false };
>DiscriminatedUnion : Symbol(DiscriminatedUnion, Decl(relatedViaDiscriminatedTypeNoError.ts, 2, 1))
>flag : Symbol(flag, Decl(relatedViaDiscriminatedTypeNoError.ts, 4, 27))
>flag : Symbol(flag, Decl(relatedViaDiscriminatedTypeNoError.ts, 4, 44))
class A<T extends DiscriminatedUnion> {
>A : Symbol(A, Decl(relatedViaDiscriminatedTypeNoError.ts, 4, 59))
>T : Symbol(T, Decl(relatedViaDiscriminatedTypeNoError.ts, 5, 8))
>DiscriminatedUnion : Symbol(DiscriminatedUnion, Decl(relatedViaDiscriminatedTypeNoError.ts, 2, 1))
constructor(public model: T) { }
>model : Symbol(A.model, Decl(relatedViaDiscriminatedTypeNoError.ts, 6, 16))
>T : Symbol(T, Decl(relatedViaDiscriminatedTypeNoError.ts, 5, 8))
}
class B extends A<Model> { }
>B : Symbol(B, Decl(relatedViaDiscriminatedTypeNoError.ts, 7, 1))
>A : Symbol(A, Decl(relatedViaDiscriminatedTypeNoError.ts, 4, 59))
>Model : Symbol(Model, Decl(relatedViaDiscriminatedTypeNoError.ts, 0, 0))
@@ -0,0 +1,26 @@
=== tests/cases/compiler/relatedViaDiscriminatedTypeNoError.ts ===
class Model {
>Model : Model
constructor(public flag: boolean) {}
>flag : boolean
}
type DiscriminatedUnion = { flag: true } | { flag: false };
>DiscriminatedUnion : { flag: true; } | { flag: false; }
>flag : true
>true : true
>flag : false
>false : false
class A<T extends DiscriminatedUnion> {
>A : A<T>
constructor(public model: T) { }
>model : T
}
class B extends A<Model> { }
>B : B
>A : A<Model>
@@ -0,0 +1,10 @@
class Model {
constructor(public flag: boolean) {}
}
type DiscriminatedUnion = { flag: true } | { flag: false };
class A<T extends DiscriminatedUnion> {
constructor(public model: T) { }
}
class B extends A<Model> { }