Propagate intersectionState in typeRelatedToSomeType (#56207)

This commit is contained in:
Anders Hejlsberg 2023-11-20 17:05:43 -08:00 committed by GitHub
parent 0abfb521d5
commit 9302332481
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 195 additions and 6 deletions

View File

@ -21565,7 +21565,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
eachTypeRelatedToType(source as UnionType, target, reportErrors && !(source.flags & TypeFlags.Primitive), intersectionState);
}
if (target.flags & TypeFlags.Union) {
return typeRelatedToSomeType(getRegularTypeOfObjectLiteral(source), target as UnionType, reportErrors && !(source.flags & TypeFlags.Primitive) && !(target.flags & TypeFlags.Primitive));
return typeRelatedToSomeType(getRegularTypeOfObjectLiteral(source), target as UnionType, reportErrors && !(source.flags & TypeFlags.Primitive) && !(target.flags & TypeFlags.Primitive), intersectionState);
}
if (target.flags & TypeFlags.Intersection) {
return typeRelatedToEachType(source, target as IntersectionType, reportErrors, IntersectionState.Target);
@ -21599,7 +21599,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
let result = Ternary.True;
const sourceTypes = source.types;
for (const sourceType of sourceTypes) {
const related = typeRelatedToSomeType(sourceType, target, /*reportErrors*/ false);
const related = typeRelatedToSomeType(sourceType, target, /*reportErrors*/ false, IntersectionState.None);
if (!related) {
return Ternary.False;
}
@ -21608,7 +21608,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
return result;
}
function typeRelatedToSomeType(source: Type, target: UnionOrIntersectionType, reportErrors: boolean): Ternary {
function typeRelatedToSomeType(source: Type, target: UnionOrIntersectionType, reportErrors: boolean, intersectionState: IntersectionState): Ternary {
const targetTypes = target.types;
if (target.flags & TypeFlags.Union) {
if (containsType(targetTypes, source)) {
@ -21635,14 +21635,14 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
}
const match = getMatchingUnionConstituentForType(target as UnionType, source);
if (match) {
const related = isRelatedTo(source, match, RecursionFlags.Target, /*reportErrors*/ false);
const related = isRelatedTo(source, match, RecursionFlags.Target, /*reportErrors*/ false, /*headMessage*/ undefined, intersectionState);
if (related) {
return related;
}
}
}
for (const type of targetTypes) {
const related = isRelatedTo(source, type, RecursionFlags.Target, /*reportErrors*/ false);
const related = isRelatedTo(source, type, RecursionFlags.Target, /*reportErrors*/ false, /*headMessage*/ undefined, intersectionState);
if (related) {
return related;
}
@ -21651,7 +21651,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
// Elaborate only if we can find a best matching type in the target union
const bestMatchingType = getBestMatchingType(source, target, isRelatedTo);
if (bestMatchingType) {
isRelatedTo(source, bestMatchingType, RecursionFlags.Target, /*reportErrors*/ true);
isRelatedTo(source, bestMatchingType, RecursionFlags.Target, /*reportErrors*/ true, /*headMessage*/ undefined, intersectionState);
}
}
return Ternary.False;

View File

@ -88,4 +88,29 @@ nestedExcessPropertyChecking.ts(40,9): error TS2559: Type 'false' has no propert
},
},
};
// Repro from #53412
type BaseItem = {
id: number;
}
type ExtendedItem = BaseItem & {
description: string | null
};
type BaseValue = {
// there are other fields
items: BaseItem[];
}
type ExtendedValue = BaseValue & {
// there are other fields
items: ExtendedItem[];
}
const TEST_VALUE: ExtendedValue = {
items: [
{id: 1, description: null},
{id: 2, description: 'wigglytubble'},
]
};

View File

@ -64,6 +64,31 @@ const response: Query = {
},
},
};
// Repro from #53412
type BaseItem = {
id: number;
}
type ExtendedItem = BaseItem & {
description: string | null
};
type BaseValue = {
// there are other fields
items: BaseItem[];
}
type ExtendedValue = BaseValue & {
// there are other fields
items: ExtendedItem[];
}
const TEST_VALUE: ExtendedValue = {
items: [
{id: 1, description: null},
{id: 2, description: 'wigglytubble'},
]
};
//// [nestedExcessPropertyChecking.js]
@ -90,3 +115,9 @@ var response = {
},
},
};
var TEST_VALUE = {
items: [
{ id: 1, description: null },
{ id: 2, description: 'wigglytubble' },
]
};

View File

@ -165,3 +165,56 @@ const response: Query = {
},
};
// Repro from #53412
type BaseItem = {
>BaseItem : Symbol(BaseItem, Decl(nestedExcessPropertyChecking.ts, 62, 2))
id: number;
>id : Symbol(id, Decl(nestedExcessPropertyChecking.ts, 66, 17))
}
type ExtendedItem = BaseItem & {
>ExtendedItem : Symbol(ExtendedItem, Decl(nestedExcessPropertyChecking.ts, 68, 1))
>BaseItem : Symbol(BaseItem, Decl(nestedExcessPropertyChecking.ts, 62, 2))
description: string | null
>description : Symbol(description, Decl(nestedExcessPropertyChecking.ts, 69, 32))
};
type BaseValue = {
>BaseValue : Symbol(BaseValue, Decl(nestedExcessPropertyChecking.ts, 71, 2))
// there are other fields
items: BaseItem[];
>items : Symbol(items, Decl(nestedExcessPropertyChecking.ts, 73, 18))
>BaseItem : Symbol(BaseItem, Decl(nestedExcessPropertyChecking.ts, 62, 2))
}
type ExtendedValue = BaseValue & {
>ExtendedValue : Symbol(ExtendedValue, Decl(nestedExcessPropertyChecking.ts, 76, 1))
>BaseValue : Symbol(BaseValue, Decl(nestedExcessPropertyChecking.ts, 71, 2))
// there are other fields
items: ExtendedItem[];
>items : Symbol(items, Decl(nestedExcessPropertyChecking.ts, 77, 34))
>ExtendedItem : Symbol(ExtendedItem, Decl(nestedExcessPropertyChecking.ts, 68, 1))
}
const TEST_VALUE: ExtendedValue = {
>TEST_VALUE : Symbol(TEST_VALUE, Decl(nestedExcessPropertyChecking.ts, 82, 5))
>ExtendedValue : Symbol(ExtendedValue, Decl(nestedExcessPropertyChecking.ts, 76, 1))
items: [
>items : Symbol(items, Decl(nestedExcessPropertyChecking.ts, 82, 35))
{id: 1, description: null},
>id : Symbol(id, Decl(nestedExcessPropertyChecking.ts, 84, 9))
>description : Symbol(description, Decl(nestedExcessPropertyChecking.ts, 84, 15))
{id: 2, description: 'wigglytubble'},
>id : Symbol(id, Decl(nestedExcessPropertyChecking.ts, 85, 9))
>description : Symbol(description, Decl(nestedExcessPropertyChecking.ts, 85, 15))
]
};

View File

@ -160,3 +160,58 @@ const response: Query = {
},
};
// Repro from #53412
type BaseItem = {
>BaseItem : { id: number; }
id: number;
>id : number
}
type ExtendedItem = BaseItem & {
>ExtendedItem : BaseItem & { description: string | null; }
description: string | null
>description : string | null
};
type BaseValue = {
>BaseValue : { items: BaseItem[]; }
// there are other fields
items: BaseItem[];
>items : BaseItem[]
}
type ExtendedValue = BaseValue & {
>ExtendedValue : BaseValue & { items: ExtendedItem[]; }
// there are other fields
items: ExtendedItem[];
>items : ExtendedItem[]
}
const TEST_VALUE: ExtendedValue = {
>TEST_VALUE : ExtendedValue
>{ items: [ {id: 1, description: null}, {id: 2, description: 'wigglytubble'}, ]} : { items: ({ id: number; description: null; } | { id: number; description: string; })[]; }
items: [
>items : ({ id: number; description: null; } | { id: number; description: string; })[]
>[ {id: 1, description: null}, {id: 2, description: 'wigglytubble'}, ] : ({ id: number; description: null; } | { id: number; description: string; })[]
{id: 1, description: null},
>{id: 1, description: null} : { id: number; description: null; }
>id : number
>1 : 1
>description : null
{id: 2, description: 'wigglytubble'},
>{id: 2, description: 'wigglytubble'} : { id: number; description: string; }
>id : number
>2 : 2
>description : string
>'wigglytubble' : "wigglytubble"
]
};

View File

@ -63,3 +63,28 @@ const response: Query = {
},
},
};
// Repro from #53412
type BaseItem = {
id: number;
}
type ExtendedItem = BaseItem & {
description: string | null
};
type BaseValue = {
// there are other fields
items: BaseItem[];
}
type ExtendedValue = BaseValue & {
// there are other fields
items: ExtendedItem[];
}
const TEST_VALUE: ExtendedValue = {
items: [
{id: 1, description: null},
{id: 2, description: 'wigglytubble'},
]
};