typeRelatedToSomeType passes through intersectionState (#43707)

* typeRelatedToSomeType passes through intersectionState

Previously it didn't, even though it should have.

* fix parameter name lint
This commit is contained in:
Nathan Shively-Sanders 2021-04-28 16:12:20 -07:00 committed by GitHub
parent 58c54127a9
commit db09cb5951
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 236 additions and 6 deletions

View File

@ -17929,7 +17929,7 @@ namespace ts {
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;
}
@ -17938,7 +17938,7 @@ namespace ts {
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)) {
@ -17946,21 +17946,21 @@ namespace ts {
}
const match = getMatchingUnionConstituentForType(<UnionType>target, source);
if (match) {
const related = isRelatedTo(source, match, /*reportErrors*/ false);
const related = isRelatedTo(source, match, /*reportErrors*/ false, /*headMessage*/ undefined, intersectionState);
if (related) {
return related;
}
}
}
for (const type of targetTypes) {
const related = isRelatedTo(source, type, /*reportErrors*/ false);
const related = isRelatedTo(source, type, /*reportErrors*/ false, /*headMessage*/ undefined, intersectionState);
if (related) {
return related;
}
}
if (reportErrors) {
const bestMatchingType = getBestMatchingType(source, target, isRelatedTo);
isRelatedTo(source, bestMatchingType || targetTypes[targetTypes.length - 1], /*reportErrors*/ true);
isRelatedTo(source, bestMatchingType || targetTypes[targetTypes.length - 1], /*reportErrors*/ true, /*headMessage*/ undefined, intersectionState);
}
return Ternary.False;
}
@ -18220,7 +18220,7 @@ namespace ts {
eachTypeRelatedToType(source as UnionType, target, reportErrors && !(source.flags & TypeFlags.Primitive), intersectionState & ~IntersectionState.UnionIntersectionCheck);
}
if (target.flags & TypeFlags.Union) {
return typeRelatedToSomeType(getRegularTypeOfObjectLiteral(source), <UnionType>target, reportErrors && !(source.flags & TypeFlags.Primitive) && !(target.flags & TypeFlags.Primitive));
return typeRelatedToSomeType(getRegularTypeOfObjectLiteral(source), <UnionType>target, reportErrors && !(source.flags & TypeFlags.Primitive) && !(target.flags & TypeFlags.Primitive), intersectionState & ~IntersectionState.UnionIntersectionCheck);
}
if (target.flags & TypeFlags.Intersection) {
return typeRelatedToEachType(getRegularTypeOfObjectLiteral(source), target as IntersectionType, reportErrors, IntersectionState.Target);

View File

@ -12,12 +12,59 @@ function getMaxId(items: NodeWithId[]) {
const nodes = [] as ITreeItem[];
getMaxId(nodes);
// Repro from #42715
export interface Donkey {
donkey: string;
}
interface Diddy {
diddy: string;
children?: Diddy[] | Donkey;
}
interface Cranky {
cranky: string;
children: Diddy;
}
type Dandy = Diddy & {
children: (Diddy & { funky?: string })[];
};
type X = Dandy["children"]
var x: X
const mainView: Dandy = {
diddy: "",
children: [
{
diddy: "",
funky: "Empty" // <- Incorrect error
}
],
};
// Legal
const p = mainView.children[0].funky
//// [recursiveExcessPropertyChecks.js]
"use strict";
// Repro from #35804
exports.__esModule = true;
function getMaxId(items) {
}
var nodes = [];
getMaxId(nodes);
var x;
var mainView = {
diddy: "",
children: [
{
diddy: "",
funky: "Empty" // <- Incorrect error
}
]
};
// Legal
var p = mainView.children[0].funky;

View File

@ -27,3 +27,80 @@ getMaxId(nodes);
>getMaxId : Symbol(getMaxId, Decl(recursiveExcessPropertyChecks.ts, 6, 46))
>nodes : Symbol(nodes, Decl(recursiveExcessPropertyChecks.ts, 11, 5))
// Repro from #42715
export interface Donkey {
>Donkey : Symbol(Donkey, Decl(recursiveExcessPropertyChecks.ts, 12, 16))
donkey: string;
>donkey : Symbol(Donkey.donkey, Decl(recursiveExcessPropertyChecks.ts, 16, 25))
}
interface Diddy {
>Diddy : Symbol(Diddy, Decl(recursiveExcessPropertyChecks.ts, 18, 1))
diddy: string;
>diddy : Symbol(Diddy.diddy, Decl(recursiveExcessPropertyChecks.ts, 20, 17))
children?: Diddy[] | Donkey;
>children : Symbol(Diddy.children, Decl(recursiveExcessPropertyChecks.ts, 21, 18))
>Diddy : Symbol(Diddy, Decl(recursiveExcessPropertyChecks.ts, 18, 1))
>Donkey : Symbol(Donkey, Decl(recursiveExcessPropertyChecks.ts, 12, 16))
}
interface Cranky {
>Cranky : Symbol(Cranky, Decl(recursiveExcessPropertyChecks.ts, 23, 1))
cranky: string;
>cranky : Symbol(Cranky.cranky, Decl(recursiveExcessPropertyChecks.ts, 25, 18))
children: Diddy;
>children : Symbol(Cranky.children, Decl(recursiveExcessPropertyChecks.ts, 26, 19))
>Diddy : Symbol(Diddy, Decl(recursiveExcessPropertyChecks.ts, 18, 1))
}
type Dandy = Diddy & {
>Dandy : Symbol(Dandy, Decl(recursiveExcessPropertyChecks.ts, 28, 1))
>Diddy : Symbol(Diddy, Decl(recursiveExcessPropertyChecks.ts, 18, 1))
children: (Diddy & { funky?: string })[];
>children : Symbol(children, Decl(recursiveExcessPropertyChecks.ts, 30, 22))
>Diddy : Symbol(Diddy, Decl(recursiveExcessPropertyChecks.ts, 18, 1))
>funky : Symbol(funky, Decl(recursiveExcessPropertyChecks.ts, 31, 24))
};
type X = Dandy["children"]
>X : Symbol(X, Decl(recursiveExcessPropertyChecks.ts, 32, 2))
>Dandy : Symbol(Dandy, Decl(recursiveExcessPropertyChecks.ts, 28, 1))
var x: X
>x : Symbol(x, Decl(recursiveExcessPropertyChecks.ts, 34, 3))
>X : Symbol(X, Decl(recursiveExcessPropertyChecks.ts, 32, 2))
const mainView: Dandy = {
>mainView : Symbol(mainView, Decl(recursiveExcessPropertyChecks.ts, 36, 5))
>Dandy : Symbol(Dandy, Decl(recursiveExcessPropertyChecks.ts, 28, 1))
diddy: "",
>diddy : Symbol(diddy, Decl(recursiveExcessPropertyChecks.ts, 36, 25))
children: [
>children : Symbol(children, Decl(recursiveExcessPropertyChecks.ts, 37, 14))
{
diddy: "",
>diddy : Symbol(diddy, Decl(recursiveExcessPropertyChecks.ts, 39, 9))
funky: "Empty" // <- Incorrect error
>funky : Symbol(funky, Decl(recursiveExcessPropertyChecks.ts, 40, 22))
}
],
};
// Legal
const p = mainView.children[0].funky
>p : Symbol(p, Decl(recursiveExcessPropertyChecks.ts, 46, 5))
>mainView.children[0].funky : Symbol(funky, Decl(recursiveExcessPropertyChecks.ts, 31, 24))
>mainView.children : Symbol(children, Decl(recursiveExcessPropertyChecks.ts, 21, 18), Decl(recursiveExcessPropertyChecks.ts, 30, 22))
>mainView : Symbol(mainView, Decl(recursiveExcessPropertyChecks.ts, 36, 5))
>children : Symbol(children, Decl(recursiveExcessPropertyChecks.ts, 21, 18), Decl(recursiveExcessPropertyChecks.ts, 30, 22))
>funky : Symbol(funky, Decl(recursiveExcessPropertyChecks.ts, 31, 24))

View File

@ -25,3 +25,75 @@ getMaxId(nodes);
>getMaxId : (items: NodeWithId[]) => void
>nodes : ITreeItem[]
// Repro from #42715
export interface Donkey {
donkey: string;
>donkey : string
}
interface Diddy {
diddy: string;
>diddy : string
children?: Diddy[] | Donkey;
>children : Donkey | Diddy[] | undefined
}
interface Cranky {
cranky: string;
>cranky : string
children: Diddy;
>children : Diddy
}
type Dandy = Diddy & {
>Dandy : Dandy
children: (Diddy & { funky?: string })[];
>children : (Diddy & { funky?: string | undefined; })[]
>funky : string | undefined
};
type X = Dandy["children"]
>X : (Donkey | Diddy[] | undefined) & (Diddy & { funky?: string | undefined; })[]
var x: X
>x : (Donkey | Diddy[] | undefined) & (Diddy & { funky?: string | undefined; })[]
const mainView: Dandy = {
>mainView : Dandy
>{ diddy: "", children: [ { diddy: "", funky: "Empty" // <- Incorrect error } ],} : { diddy: string; children: { diddy: string; funky: string; }[]; }
diddy: "",
>diddy : string
>"" : ""
children: [
>children : { diddy: string; funky: string; }[]
>[ { diddy: "", funky: "Empty" // <- Incorrect error } ] : { diddy: string; funky: string; }[]
{
>{ diddy: "", funky: "Empty" // <- Incorrect error } : { diddy: string; funky: string; }
diddy: "",
>diddy : string
>"" : ""
funky: "Empty" // <- Incorrect error
>funky : string
>"Empty" : "Empty"
}
],
};
// Legal
const p = mainView.children[0].funky
>p : string | undefined
>mainView.children[0].funky : string | undefined
>mainView.children[0] : Diddy & { funky?: string | undefined; }
>mainView.children : (Donkey | Diddy[] | undefined) & (Diddy & { funky?: string | undefined; })[]
>mainView : Dandy
>children : (Donkey | Diddy[] | undefined) & (Diddy & { funky?: string | undefined; })[]
>0 : 0
>funky : string | undefined

View File

@ -13,3 +13,37 @@ function getMaxId(items: NodeWithId[]) {
const nodes = [] as ITreeItem[];
getMaxId(nodes);
// Repro from #42715
export interface Donkey {
donkey: string;
}
interface Diddy {
diddy: string;
children?: Diddy[] | Donkey;
}
interface Cranky {
cranky: string;
children: Diddy;
}
type Dandy = Diddy & {
children: (Diddy & { funky?: string })[];
};
type X = Dandy["children"]
var x: X
const mainView: Dandy = {
diddy: "",
children: [
{
diddy: "",
funky: "Empty" // <- Incorrect error
}
],
};
// Legal
const p = mainView.children[0].funky