Skip to content

Commit db09cb5

Browse files
authored
typeRelatedToSomeType passes through intersectionState (#43707)
* typeRelatedToSomeType passes through intersectionState Previously it didn't, even though it should have. * fix parameter name lint
1 parent 58c5412 commit db09cb5

File tree

5 files changed

+236
-6
lines changed

5 files changed

+236
-6
lines changed

src/compiler/checker.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17929,7 +17929,7 @@ namespace ts {
1792917929
let result = Ternary.True;
1793017930
const sourceTypes = source.types;
1793117931
for (const sourceType of sourceTypes) {
17932-
const related = typeRelatedToSomeType(sourceType, target, /*reportErrors*/ false);
17932+
const related = typeRelatedToSomeType(sourceType, target, /*reportErrors*/ false, IntersectionState.None);
1793317933
if (!related) {
1793417934
return Ternary.False;
1793517935
}
@@ -17938,29 +17938,29 @@ namespace ts {
1793817938
return result;
1793917939
}
1794017940

17941-
function typeRelatedToSomeType(source: Type, target: UnionOrIntersectionType, reportErrors: boolean): Ternary {
17941+
function typeRelatedToSomeType(source: Type, target: UnionOrIntersectionType, reportErrors: boolean, intersectionState: IntersectionState): Ternary {
1794217942
const targetTypes = target.types;
1794317943
if (target.flags & TypeFlags.Union) {
1794417944
if (containsType(targetTypes, source)) {
1794517945
return Ternary.True;
1794617946
}
1794717947
const match = getMatchingUnionConstituentForType(<UnionType>target, source);
1794817948
if (match) {
17949-
const related = isRelatedTo(source, match, /*reportErrors*/ false);
17949+
const related = isRelatedTo(source, match, /*reportErrors*/ false, /*headMessage*/ undefined, intersectionState);
1795017950
if (related) {
1795117951
return related;
1795217952
}
1795317953
}
1795417954
}
1795517955
for (const type of targetTypes) {
17956-
const related = isRelatedTo(source, type, /*reportErrors*/ false);
17956+
const related = isRelatedTo(source, type, /*reportErrors*/ false, /*headMessage*/ undefined, intersectionState);
1795717957
if (related) {
1795817958
return related;
1795917959
}
1796017960
}
1796117961
if (reportErrors) {
1796217962
const bestMatchingType = getBestMatchingType(source, target, isRelatedTo);
17963-
isRelatedTo(source, bestMatchingType || targetTypes[targetTypes.length - 1], /*reportErrors*/ true);
17963+
isRelatedTo(source, bestMatchingType || targetTypes[targetTypes.length - 1], /*reportErrors*/ true, /*headMessage*/ undefined, intersectionState);
1796417964
}
1796517965
return Ternary.False;
1796617966
}
@@ -18220,7 +18220,7 @@ namespace ts {
1822018220
eachTypeRelatedToType(source as UnionType, target, reportErrors && !(source.flags & TypeFlags.Primitive), intersectionState & ~IntersectionState.UnionIntersectionCheck);
1822118221
}
1822218222
if (target.flags & TypeFlags.Union) {
18223-
return typeRelatedToSomeType(getRegularTypeOfObjectLiteral(source), <UnionType>target, reportErrors && !(source.flags & TypeFlags.Primitive) && !(target.flags & TypeFlags.Primitive));
18223+
return typeRelatedToSomeType(getRegularTypeOfObjectLiteral(source), <UnionType>target, reportErrors && !(source.flags & TypeFlags.Primitive) && !(target.flags & TypeFlags.Primitive), intersectionState & ~IntersectionState.UnionIntersectionCheck);
1822418224
}
1822518225
if (target.flags & TypeFlags.Intersection) {
1822618226
return typeRelatedToEachType(getRegularTypeOfObjectLiteral(source), target as IntersectionType, reportErrors, IntersectionState.Target);

tests/baselines/reference/recursiveExcessPropertyChecks.js

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,59 @@ function getMaxId(items: NodeWithId[]) {
1212

1313
const nodes = [] as ITreeItem[];
1414
getMaxId(nodes);
15+
16+
17+
// Repro from #42715
18+
export interface Donkey {
19+
donkey: string;
20+
}
21+
22+
interface Diddy {
23+
diddy: string;
24+
children?: Diddy[] | Donkey;
25+
}
26+
27+
interface Cranky {
28+
cranky: string;
29+
children: Diddy;
30+
}
31+
32+
type Dandy = Diddy & {
33+
children: (Diddy & { funky?: string })[];
34+
};
35+
type X = Dandy["children"]
36+
var x: X
37+
38+
const mainView: Dandy = {
39+
diddy: "",
40+
children: [
41+
{
42+
diddy: "",
43+
funky: "Empty" // <- Incorrect error
44+
}
45+
],
46+
};
47+
// Legal
48+
const p = mainView.children[0].funky
1549

1650

1751
//// [recursiveExcessPropertyChecks.js]
1852
"use strict";
1953
// Repro from #35804
54+
exports.__esModule = true;
2055
function getMaxId(items) {
2156
}
2257
var nodes = [];
2358
getMaxId(nodes);
59+
var x;
60+
var mainView = {
61+
diddy: "",
62+
children: [
63+
{
64+
diddy: "",
65+
funky: "Empty" // <- Incorrect error
66+
}
67+
]
68+
};
69+
// Legal
70+
var p = mainView.children[0].funky;

tests/baselines/reference/recursiveExcessPropertyChecks.symbols

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,3 +27,80 @@ getMaxId(nodes);
2727
>getMaxId : Symbol(getMaxId, Decl(recursiveExcessPropertyChecks.ts, 6, 46))
2828
>nodes : Symbol(nodes, Decl(recursiveExcessPropertyChecks.ts, 11, 5))
2929

30+
31+
// Repro from #42715
32+
export interface Donkey {
33+
>Donkey : Symbol(Donkey, Decl(recursiveExcessPropertyChecks.ts, 12, 16))
34+
35+
donkey: string;
36+
>donkey : Symbol(Donkey.donkey, Decl(recursiveExcessPropertyChecks.ts, 16, 25))
37+
}
38+
39+
interface Diddy {
40+
>Diddy : Symbol(Diddy, Decl(recursiveExcessPropertyChecks.ts, 18, 1))
41+
42+
diddy: string;
43+
>diddy : Symbol(Diddy.diddy, Decl(recursiveExcessPropertyChecks.ts, 20, 17))
44+
45+
children?: Diddy[] | Donkey;
46+
>children : Symbol(Diddy.children, Decl(recursiveExcessPropertyChecks.ts, 21, 18))
47+
>Diddy : Symbol(Diddy, Decl(recursiveExcessPropertyChecks.ts, 18, 1))
48+
>Donkey : Symbol(Donkey, Decl(recursiveExcessPropertyChecks.ts, 12, 16))
49+
}
50+
51+
interface Cranky {
52+
>Cranky : Symbol(Cranky, Decl(recursiveExcessPropertyChecks.ts, 23, 1))
53+
54+
cranky: string;
55+
>cranky : Symbol(Cranky.cranky, Decl(recursiveExcessPropertyChecks.ts, 25, 18))
56+
57+
children: Diddy;
58+
>children : Symbol(Cranky.children, Decl(recursiveExcessPropertyChecks.ts, 26, 19))
59+
>Diddy : Symbol(Diddy, Decl(recursiveExcessPropertyChecks.ts, 18, 1))
60+
}
61+
62+
type Dandy = Diddy & {
63+
>Dandy : Symbol(Dandy, Decl(recursiveExcessPropertyChecks.ts, 28, 1))
64+
>Diddy : Symbol(Diddy, Decl(recursiveExcessPropertyChecks.ts, 18, 1))
65+
66+
children: (Diddy & { funky?: string })[];
67+
>children : Symbol(children, Decl(recursiveExcessPropertyChecks.ts, 30, 22))
68+
>Diddy : Symbol(Diddy, Decl(recursiveExcessPropertyChecks.ts, 18, 1))
69+
>funky : Symbol(funky, Decl(recursiveExcessPropertyChecks.ts, 31, 24))
70+
71+
};
72+
type X = Dandy["children"]
73+
>X : Symbol(X, Decl(recursiveExcessPropertyChecks.ts, 32, 2))
74+
>Dandy : Symbol(Dandy, Decl(recursiveExcessPropertyChecks.ts, 28, 1))
75+
76+
var x: X
77+
>x : Symbol(x, Decl(recursiveExcessPropertyChecks.ts, 34, 3))
78+
>X : Symbol(X, Decl(recursiveExcessPropertyChecks.ts, 32, 2))
79+
80+
const mainView: Dandy = {
81+
>mainView : Symbol(mainView, Decl(recursiveExcessPropertyChecks.ts, 36, 5))
82+
>Dandy : Symbol(Dandy, Decl(recursiveExcessPropertyChecks.ts, 28, 1))
83+
84+
diddy: "",
85+
>diddy : Symbol(diddy, Decl(recursiveExcessPropertyChecks.ts, 36, 25))
86+
87+
children: [
88+
>children : Symbol(children, Decl(recursiveExcessPropertyChecks.ts, 37, 14))
89+
{
90+
diddy: "",
91+
>diddy : Symbol(diddy, Decl(recursiveExcessPropertyChecks.ts, 39, 9))
92+
93+
funky: "Empty" // <- Incorrect error
94+
>funky : Symbol(funky, Decl(recursiveExcessPropertyChecks.ts, 40, 22))
95+
}
96+
],
97+
};
98+
// Legal
99+
const p = mainView.children[0].funky
100+
>p : Symbol(p, Decl(recursiveExcessPropertyChecks.ts, 46, 5))
101+
>mainView.children[0].funky : Symbol(funky, Decl(recursiveExcessPropertyChecks.ts, 31, 24))
102+
>mainView.children : Symbol(children, Decl(recursiveExcessPropertyChecks.ts, 21, 18), Decl(recursiveExcessPropertyChecks.ts, 30, 22))
103+
>mainView : Symbol(mainView, Decl(recursiveExcessPropertyChecks.ts, 36, 5))
104+
>children : Symbol(children, Decl(recursiveExcessPropertyChecks.ts, 21, 18), Decl(recursiveExcessPropertyChecks.ts, 30, 22))
105+
>funky : Symbol(funky, Decl(recursiveExcessPropertyChecks.ts, 31, 24))
106+

tests/baselines/reference/recursiveExcessPropertyChecks.types

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,3 +25,75 @@ getMaxId(nodes);
2525
>getMaxId : (items: NodeWithId[]) => void
2626
>nodes : ITreeItem[]
2727

28+
29+
// Repro from #42715
30+
export interface Donkey {
31+
donkey: string;
32+
>donkey : string
33+
}
34+
35+
interface Diddy {
36+
diddy: string;
37+
>diddy : string
38+
39+
children?: Diddy[] | Donkey;
40+
>children : Donkey | Diddy[] | undefined
41+
}
42+
43+
interface Cranky {
44+
cranky: string;
45+
>cranky : string
46+
47+
children: Diddy;
48+
>children : Diddy
49+
}
50+
51+
type Dandy = Diddy & {
52+
>Dandy : Dandy
53+
54+
children: (Diddy & { funky?: string })[];
55+
>children : (Diddy & { funky?: string | undefined; })[]
56+
>funky : string | undefined
57+
58+
};
59+
type X = Dandy["children"]
60+
>X : (Donkey | Diddy[] | undefined) & (Diddy & { funky?: string | undefined; })[]
61+
62+
var x: X
63+
>x : (Donkey | Diddy[] | undefined) & (Diddy & { funky?: string | undefined; })[]
64+
65+
const mainView: Dandy = {
66+
>mainView : Dandy
67+
>{ diddy: "", children: [ { diddy: "", funky: "Empty" // <- Incorrect error } ],} : { diddy: string; children: { diddy: string; funky: string; }[]; }
68+
69+
diddy: "",
70+
>diddy : string
71+
>"" : ""
72+
73+
children: [
74+
>children : { diddy: string; funky: string; }[]
75+
>[ { diddy: "", funky: "Empty" // <- Incorrect error } ] : { diddy: string; funky: string; }[]
76+
{
77+
>{ diddy: "", funky: "Empty" // <- Incorrect error } : { diddy: string; funky: string; }
78+
79+
diddy: "",
80+
>diddy : string
81+
>"" : ""
82+
83+
funky: "Empty" // <- Incorrect error
84+
>funky : string
85+
>"Empty" : "Empty"
86+
}
87+
],
88+
};
89+
// Legal
90+
const p = mainView.children[0].funky
91+
>p : string | undefined
92+
>mainView.children[0].funky : string | undefined
93+
>mainView.children[0] : Diddy & { funky?: string | undefined; }
94+
>mainView.children : (Donkey | Diddy[] | undefined) & (Diddy & { funky?: string | undefined; })[]
95+
>mainView : Dandy
96+
>children : (Donkey | Diddy[] | undefined) & (Diddy & { funky?: string | undefined; })[]
97+
>0 : 0
98+
>funky : string | undefined
99+

tests/cases/compiler/recursiveExcessPropertyChecks.ts

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,3 +13,37 @@ function getMaxId(items: NodeWithId[]) {
1313

1414
const nodes = [] as ITreeItem[];
1515
getMaxId(nodes);
16+
17+
18+
// Repro from #42715
19+
export interface Donkey {
20+
donkey: string;
21+
}
22+
23+
interface Diddy {
24+
diddy: string;
25+
children?: Diddy[] | Donkey;
26+
}
27+
28+
interface Cranky {
29+
cranky: string;
30+
children: Diddy;
31+
}
32+
33+
type Dandy = Diddy & {
34+
children: (Diddy & { funky?: string })[];
35+
};
36+
type X = Dandy["children"]
37+
var x: X
38+
39+
const mainView: Dandy = {
40+
diddy: "",
41+
children: [
42+
{
43+
diddy: "",
44+
funky: "Empty" // <- Incorrect error
45+
}
46+
],
47+
};
48+
// Legal
49+
const p = mainView.children[0].funky

0 commit comments

Comments
 (0)