Skip to content

Commit 4c440e5

Browse files
Fix microsoft#31319 : Narrow unit-unit inequality tests using comparability (microsoft#33071)
* Narrow unit-unit inequality tests using comparability * Accept updated baselines Co-authored-by: Wesley Wigham <[email protected]>
1 parent 64cb578 commit 4c440e5

File tree

5 files changed

+221
-3
lines changed

5 files changed

+221
-3
lines changed

src/compiler/checker.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20366,7 +20366,7 @@ namespace ts {
2036620366
}
2036720367
if (isUnitType(valueType)) {
2036820368
const regularType = getRegularTypeOfLiteralType(valueType);
20369-
return filterType(type, t => getRegularTypeOfLiteralType(t) !== regularType);
20369+
return filterType(type, t => isUnitType(t) ? !areTypesComparable(t, valueType) : getRegularTypeOfLiteralType(t) !== regularType);
2037020370
}
2037120371
return type;
2037220372
}

tests/baselines/reference/discriminantsAndPrimitives.js

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,40 @@ function f4(x: Foo | Bar | string | number | null) {
4545
x.name;
4646
}
4747
}
48-
}
48+
}
49+
50+
// Repro from #31319
51+
52+
const enum EnumTypeNode {
53+
Pattern = "Pattern",
54+
Disjunction = "Disjunction",
55+
}
56+
57+
type NodeA = Disjunction | Pattern;
58+
59+
interface NodeBase {
60+
type: NodeA["type"]
61+
}
62+
63+
interface Disjunction extends NodeBase {
64+
type: EnumTypeNode.Disjunction
65+
alternatives: string[]
66+
}
67+
68+
interface Pattern extends NodeBase {
69+
type: EnumTypeNode.Pattern
70+
elements: string[]
71+
}
72+
73+
let n!: NodeA
74+
75+
if (n.type === "Disjunction") {
76+
n.alternatives.slice()
77+
}
78+
else {
79+
n.elements.slice() // n should be narrowed to Pattern
80+
}
81+
4982

5083
//// [discriminantsAndPrimitives.js]
5184
// Repro from #10257 plus other tests
@@ -81,3 +114,10 @@ function f4(x) {
81114
}
82115
}
83116
}
117+
var n;
118+
if (n.type === "Disjunction") {
119+
n.alternatives.slice();
120+
}
121+
else {
122+
n.elements.slice(); // n should be narrowed to Pattern
123+
}

tests/baselines/reference/discriminantsAndPrimitives.symbols

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,3 +114,80 @@ function f4(x: Foo | Bar | string | number | null) {
114114
}
115115
}
116116
}
117+
118+
// Repro from #31319
119+
120+
const enum EnumTypeNode {
121+
>EnumTypeNode : Symbol(EnumTypeNode, Decl(discriminantsAndPrimitives.ts, 46, 1))
122+
123+
Pattern = "Pattern",
124+
>Pattern : Symbol(EnumTypeNode.Pattern, Decl(discriminantsAndPrimitives.ts, 50, 25))
125+
126+
Disjunction = "Disjunction",
127+
>Disjunction : Symbol(EnumTypeNode.Disjunction, Decl(discriminantsAndPrimitives.ts, 51, 24))
128+
}
129+
130+
type NodeA = Disjunction | Pattern;
131+
>NodeA : Symbol(NodeA, Decl(discriminantsAndPrimitives.ts, 53, 1))
132+
>Disjunction : Symbol(Disjunction, Decl(discriminantsAndPrimitives.ts, 59, 1))
133+
>Pattern : Symbol(Pattern, Decl(discriminantsAndPrimitives.ts, 64, 1))
134+
135+
interface NodeBase {
136+
>NodeBase : Symbol(NodeBase, Decl(discriminantsAndPrimitives.ts, 55, 35))
137+
138+
type: NodeA["type"]
139+
>type : Symbol(NodeBase.type, Decl(discriminantsAndPrimitives.ts, 57, 20))
140+
>NodeA : Symbol(NodeA, Decl(discriminantsAndPrimitives.ts, 53, 1))
141+
}
142+
143+
interface Disjunction extends NodeBase {
144+
>Disjunction : Symbol(Disjunction, Decl(discriminantsAndPrimitives.ts, 59, 1))
145+
>NodeBase : Symbol(NodeBase, Decl(discriminantsAndPrimitives.ts, 55, 35))
146+
147+
type: EnumTypeNode.Disjunction
148+
>type : Symbol(Disjunction.type, Decl(discriminantsAndPrimitives.ts, 61, 40))
149+
>EnumTypeNode : Symbol(EnumTypeNode, Decl(discriminantsAndPrimitives.ts, 46, 1))
150+
>Disjunction : Symbol(EnumTypeNode.Disjunction, Decl(discriminantsAndPrimitives.ts, 51, 24))
151+
152+
alternatives: string[]
153+
>alternatives : Symbol(Disjunction.alternatives, Decl(discriminantsAndPrimitives.ts, 62, 34))
154+
}
155+
156+
interface Pattern extends NodeBase {
157+
>Pattern : Symbol(Pattern, Decl(discriminantsAndPrimitives.ts, 64, 1))
158+
>NodeBase : Symbol(NodeBase, Decl(discriminantsAndPrimitives.ts, 55, 35))
159+
160+
type: EnumTypeNode.Pattern
161+
>type : Symbol(Pattern.type, Decl(discriminantsAndPrimitives.ts, 66, 36))
162+
>EnumTypeNode : Symbol(EnumTypeNode, Decl(discriminantsAndPrimitives.ts, 46, 1))
163+
>Pattern : Symbol(EnumTypeNode.Pattern, Decl(discriminantsAndPrimitives.ts, 50, 25))
164+
165+
elements: string[]
166+
>elements : Symbol(Pattern.elements, Decl(discriminantsAndPrimitives.ts, 67, 30))
167+
}
168+
169+
let n!: NodeA
170+
>n : Symbol(n, Decl(discriminantsAndPrimitives.ts, 71, 3))
171+
>NodeA : Symbol(NodeA, Decl(discriminantsAndPrimitives.ts, 53, 1))
172+
173+
if (n.type === "Disjunction") {
174+
>n.type : Symbol(type, Decl(discriminantsAndPrimitives.ts, 61, 40), Decl(discriminantsAndPrimitives.ts, 66, 36))
175+
>n : Symbol(n, Decl(discriminantsAndPrimitives.ts, 71, 3))
176+
>type : Symbol(type, Decl(discriminantsAndPrimitives.ts, 61, 40), Decl(discriminantsAndPrimitives.ts, 66, 36))
177+
178+
n.alternatives.slice()
179+
>n.alternatives.slice : Symbol(Array.slice, Decl(lib.es5.d.ts, --, --))
180+
>n.alternatives : Symbol(Disjunction.alternatives, Decl(discriminantsAndPrimitives.ts, 62, 34))
181+
>n : Symbol(n, Decl(discriminantsAndPrimitives.ts, 71, 3))
182+
>alternatives : Symbol(Disjunction.alternatives, Decl(discriminantsAndPrimitives.ts, 62, 34))
183+
>slice : Symbol(Array.slice, Decl(lib.es5.d.ts, --, --))
184+
}
185+
else {
186+
n.elements.slice() // n should be narrowed to Pattern
187+
>n.elements.slice : Symbol(Array.slice, Decl(lib.es5.d.ts, --, --))
188+
>n.elements : Symbol(Pattern.elements, Decl(discriminantsAndPrimitives.ts, 67, 30))
189+
>n : Symbol(n, Decl(discriminantsAndPrimitives.ts, 71, 3))
190+
>elements : Symbol(Pattern.elements, Decl(discriminantsAndPrimitives.ts, 67, 30))
191+
>slice : Symbol(Array.slice, Decl(lib.es5.d.ts, --, --))
192+
}
193+

tests/baselines/reference/discriminantsAndPrimitives.types

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,3 +126,72 @@ function f4(x: Foo | Bar | string | number | null) {
126126
}
127127
}
128128
}
129+
130+
// Repro from #31319
131+
132+
const enum EnumTypeNode {
133+
>EnumTypeNode : EnumTypeNode
134+
135+
Pattern = "Pattern",
136+
>Pattern : EnumTypeNode.Pattern
137+
>"Pattern" : "Pattern"
138+
139+
Disjunction = "Disjunction",
140+
>Disjunction : EnumTypeNode.Disjunction
141+
>"Disjunction" : "Disjunction"
142+
}
143+
144+
type NodeA = Disjunction | Pattern;
145+
>NodeA : NodeA
146+
147+
interface NodeBase {
148+
type: NodeA["type"]
149+
>type : EnumTypeNode
150+
}
151+
152+
interface Disjunction extends NodeBase {
153+
type: EnumTypeNode.Disjunction
154+
>type : EnumTypeNode.Disjunction
155+
>EnumTypeNode : any
156+
157+
alternatives: string[]
158+
>alternatives : string[]
159+
}
160+
161+
interface Pattern extends NodeBase {
162+
type: EnumTypeNode.Pattern
163+
>type : EnumTypeNode.Pattern
164+
>EnumTypeNode : any
165+
166+
elements: string[]
167+
>elements : string[]
168+
}
169+
170+
let n!: NodeA
171+
>n : NodeA
172+
173+
if (n.type === "Disjunction") {
174+
>n.type === "Disjunction" : boolean
175+
>n.type : EnumTypeNode
176+
>n : NodeA
177+
>type : EnumTypeNode
178+
>"Disjunction" : "Disjunction"
179+
180+
n.alternatives.slice()
181+
>n.alternatives.slice() : string[]
182+
>n.alternatives.slice : (start?: number | undefined, end?: number | undefined) => string[]
183+
>n.alternatives : string[]
184+
>n : Disjunction
185+
>alternatives : string[]
186+
>slice : (start?: number | undefined, end?: number | undefined) => string[]
187+
}
188+
else {
189+
n.elements.slice() // n should be narrowed to Pattern
190+
>n.elements.slice() : string[]
191+
>n.elements.slice : (start?: number | undefined, end?: number | undefined) => string[]
192+
>n.elements : string[]
193+
>n : Pattern
194+
>elements : string[]
195+
>slice : (start?: number | undefined, end?: number | undefined) => string[]
196+
}
197+

tests/cases/compiler/discriminantsAndPrimitives.ts

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,4 +46,36 @@ function f4(x: Foo | Bar | string | number | null) {
4646
x.name;
4747
}
4848
}
49-
}
49+
}
50+
51+
// Repro from #31319
52+
53+
const enum EnumTypeNode {
54+
Pattern = "Pattern",
55+
Disjunction = "Disjunction",
56+
}
57+
58+
type NodeA = Disjunction | Pattern;
59+
60+
interface NodeBase {
61+
type: NodeA["type"]
62+
}
63+
64+
interface Disjunction extends NodeBase {
65+
type: EnumTypeNode.Disjunction
66+
alternatives: string[]
67+
}
68+
69+
interface Pattern extends NodeBase {
70+
type: EnumTypeNode.Pattern
71+
elements: string[]
72+
}
73+
74+
let n!: NodeA
75+
76+
if (n.type === "Disjunction") {
77+
n.alternatives.slice()
78+
}
79+
else {
80+
n.elements.slice() // n should be narrowed to Pattern
81+
}

0 commit comments

Comments
 (0)