Skip to content

Commit fb717df

Browse files
Discard union types before considering weak type checks on unit-like types (#50423)
* Only check isUnitType when dealing with non-unions. * Add test case. * Accepted baselines.
1 parent b9a5bbc commit fb717df

File tree

5 files changed

+315
-1
lines changed

5 files changed

+315
-1
lines changed

src/compiler/checker.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18901,7 +18901,7 @@ namespace ts {
1890118901
}
1890218902
}
1890318903

18904-
const isPerformingCommonPropertyChecks = (relation !== comparableRelation || relation === comparableRelation && isLiteralType(source)) &&
18904+
const isPerformingCommonPropertyChecks = (relation !== comparableRelation || !(source.flags & TypeFlags.Union) && isLiteralType(source)) &&
1890518905
!(intersectionState & IntersectionState.Target) &&
1890618906
source.flags & (TypeFlags.Primitive | TypeFlags.Object | TypeFlags.Intersection) && source !== globalObjectType &&
1890718907
target.flags & (TypeFlags.Object | TypeFlags.Intersection) && isWeakType(target) &&
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
//// [weakTypesAndLiterals01.ts]
2+
type WeakTypes =
3+
| { optional?: true; }
4+
| { toLowerCase?(): string }
5+
| { toUpperCase?(): string, otherOptionalProp?: number };
6+
7+
type LiteralsOrWeakTypes =
8+
| "A"
9+
| "B"
10+
| WeakTypes;
11+
12+
declare let aOrB: "A" | "B";
13+
14+
const f = (arg: LiteralsOrWeakTypes) => {
15+
if (arg === "A") {
16+
return arg;
17+
}
18+
else {
19+
return arg;
20+
}
21+
}
22+
23+
const g = (arg: WeakTypes) => {
24+
if (arg === "A") {
25+
return arg;
26+
}
27+
else {
28+
return arg;
29+
}
30+
}
31+
32+
const h = (arg: LiteralsOrWeakTypes) => {
33+
if (arg === aOrB) {
34+
return arg;
35+
}
36+
else {
37+
return arg;
38+
}
39+
}
40+
41+
const i = (arg: WeakTypes) => {
42+
if (arg === aOrB) {
43+
return arg;
44+
}
45+
else {
46+
return arg;
47+
}
48+
}
49+
50+
51+
52+
53+
//// [weakTypesAndLiterals01.d.ts]
54+
type WeakTypes = {
55+
optional?: true;
56+
} | {
57+
toLowerCase?(): string;
58+
} | {
59+
toUpperCase?(): string;
60+
otherOptionalProp?: number;
61+
};
62+
type LiteralsOrWeakTypes = "A" | "B" | WeakTypes;
63+
declare let aOrB: "A" | "B";
64+
declare const f: (arg: LiteralsOrWeakTypes) => WeakTypes | "A" | "B";
65+
declare const g: (arg: WeakTypes) => WeakTypes;
66+
declare const h: (arg: LiteralsOrWeakTypes) => LiteralsOrWeakTypes;
67+
declare const i: (arg: WeakTypes) => WeakTypes;
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
=== tests/cases/conformance/types/typeRelationships/comparable/weakTypesAndLiterals01.ts ===
2+
type WeakTypes =
3+
>WeakTypes : Symbol(WeakTypes, Decl(weakTypesAndLiterals01.ts, 0, 0))
4+
5+
| { optional?: true; }
6+
>optional : Symbol(optional, Decl(weakTypesAndLiterals01.ts, 1, 7))
7+
8+
| { toLowerCase?(): string }
9+
>toLowerCase : Symbol(toLowerCase, Decl(weakTypesAndLiterals01.ts, 2, 7))
10+
11+
| { toUpperCase?(): string, otherOptionalProp?: number };
12+
>toUpperCase : Symbol(toUpperCase, Decl(weakTypesAndLiterals01.ts, 3, 7))
13+
>otherOptionalProp : Symbol(otherOptionalProp, Decl(weakTypesAndLiterals01.ts, 3, 31))
14+
15+
type LiteralsOrWeakTypes =
16+
>LiteralsOrWeakTypes : Symbol(LiteralsOrWeakTypes, Decl(weakTypesAndLiterals01.ts, 3, 61))
17+
18+
| "A"
19+
| "B"
20+
| WeakTypes;
21+
>WeakTypes : Symbol(WeakTypes, Decl(weakTypesAndLiterals01.ts, 0, 0))
22+
23+
declare let aOrB: "A" | "B";
24+
>aOrB : Symbol(aOrB, Decl(weakTypesAndLiterals01.ts, 10, 11))
25+
26+
const f = (arg: LiteralsOrWeakTypes) => {
27+
>f : Symbol(f, Decl(weakTypesAndLiterals01.ts, 12, 5))
28+
>arg : Symbol(arg, Decl(weakTypesAndLiterals01.ts, 12, 11))
29+
>LiteralsOrWeakTypes : Symbol(LiteralsOrWeakTypes, Decl(weakTypesAndLiterals01.ts, 3, 61))
30+
31+
if (arg === "A") {
32+
>arg : Symbol(arg, Decl(weakTypesAndLiterals01.ts, 12, 11))
33+
34+
return arg;
35+
>arg : Symbol(arg, Decl(weakTypesAndLiterals01.ts, 12, 11))
36+
}
37+
else {
38+
return arg;
39+
>arg : Symbol(arg, Decl(weakTypesAndLiterals01.ts, 12, 11))
40+
}
41+
}
42+
43+
const g = (arg: WeakTypes) => {
44+
>g : Symbol(g, Decl(weakTypesAndLiterals01.ts, 21, 5))
45+
>arg : Symbol(arg, Decl(weakTypesAndLiterals01.ts, 21, 11))
46+
>WeakTypes : Symbol(WeakTypes, Decl(weakTypesAndLiterals01.ts, 0, 0))
47+
48+
if (arg === "A") {
49+
>arg : Symbol(arg, Decl(weakTypesAndLiterals01.ts, 21, 11))
50+
51+
return arg;
52+
>arg : Symbol(arg, Decl(weakTypesAndLiterals01.ts, 21, 11))
53+
}
54+
else {
55+
return arg;
56+
>arg : Symbol(arg, Decl(weakTypesAndLiterals01.ts, 21, 11))
57+
}
58+
}
59+
60+
const h = (arg: LiteralsOrWeakTypes) => {
61+
>h : Symbol(h, Decl(weakTypesAndLiterals01.ts, 30, 5))
62+
>arg : Symbol(arg, Decl(weakTypesAndLiterals01.ts, 30, 11))
63+
>LiteralsOrWeakTypes : Symbol(LiteralsOrWeakTypes, Decl(weakTypesAndLiterals01.ts, 3, 61))
64+
65+
if (arg === aOrB) {
66+
>arg : Symbol(arg, Decl(weakTypesAndLiterals01.ts, 30, 11))
67+
>aOrB : Symbol(aOrB, Decl(weakTypesAndLiterals01.ts, 10, 11))
68+
69+
return arg;
70+
>arg : Symbol(arg, Decl(weakTypesAndLiterals01.ts, 30, 11))
71+
}
72+
else {
73+
return arg;
74+
>arg : Symbol(arg, Decl(weakTypesAndLiterals01.ts, 30, 11))
75+
}
76+
}
77+
78+
const i = (arg: WeakTypes) => {
79+
>i : Symbol(i, Decl(weakTypesAndLiterals01.ts, 39, 5))
80+
>arg : Symbol(arg, Decl(weakTypesAndLiterals01.ts, 39, 11))
81+
>WeakTypes : Symbol(WeakTypes, Decl(weakTypesAndLiterals01.ts, 0, 0))
82+
83+
if (arg === aOrB) {
84+
>arg : Symbol(arg, Decl(weakTypesAndLiterals01.ts, 39, 11))
85+
>aOrB : Symbol(aOrB, Decl(weakTypesAndLiterals01.ts, 10, 11))
86+
87+
return arg;
88+
>arg : Symbol(arg, Decl(weakTypesAndLiterals01.ts, 39, 11))
89+
}
90+
else {
91+
return arg;
92+
>arg : Symbol(arg, Decl(weakTypesAndLiterals01.ts, 39, 11))
93+
}
94+
}
95+
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
=== tests/cases/conformance/types/typeRelationships/comparable/weakTypesAndLiterals01.ts ===
2+
type WeakTypes =
3+
>WeakTypes : { optional?: true | undefined; } | { toLowerCase?(): string; } | { toUpperCase?(): string; otherOptionalProp?: number | undefined; }
4+
5+
| { optional?: true; }
6+
>optional : true | undefined
7+
>true : true
8+
9+
| { toLowerCase?(): string }
10+
>toLowerCase : (() => string) | undefined
11+
12+
| { toUpperCase?(): string, otherOptionalProp?: number };
13+
>toUpperCase : (() => string) | undefined
14+
>otherOptionalProp : number | undefined
15+
16+
type LiteralsOrWeakTypes =
17+
>LiteralsOrWeakTypes : WeakTypes | "A" | "B"
18+
19+
| "A"
20+
| "B"
21+
| WeakTypes;
22+
23+
declare let aOrB: "A" | "B";
24+
>aOrB : "A" | "B"
25+
26+
const f = (arg: LiteralsOrWeakTypes) => {
27+
>f : (arg: LiteralsOrWeakTypes) => WeakTypes | "A" | "B"
28+
>(arg: LiteralsOrWeakTypes) => { if (arg === "A") { return arg; } else { return arg; }} : (arg: LiteralsOrWeakTypes) => WeakTypes | "A" | "B"
29+
>arg : LiteralsOrWeakTypes
30+
31+
if (arg === "A") {
32+
>arg === "A" : boolean
33+
>arg : LiteralsOrWeakTypes
34+
>"A" : "A"
35+
36+
return arg;
37+
>arg : { toLowerCase?(): string; } | { toUpperCase?(): string; otherOptionalProp?: number | undefined; } | "A"
38+
}
39+
else {
40+
return arg;
41+
>arg : WeakTypes | "B"
42+
}
43+
}
44+
45+
const g = (arg: WeakTypes) => {
46+
>g : (arg: WeakTypes) => WeakTypes
47+
>(arg: WeakTypes) => { if (arg === "A") { return arg; } else { return arg; }} : (arg: WeakTypes) => WeakTypes
48+
>arg : WeakTypes
49+
50+
if (arg === "A") {
51+
>arg === "A" : boolean
52+
>arg : WeakTypes
53+
>"A" : "A"
54+
55+
return arg;
56+
>arg : { toLowerCase?(): string; } | { toUpperCase?(): string; otherOptionalProp?: number | undefined; }
57+
}
58+
else {
59+
return arg;
60+
>arg : WeakTypes
61+
}
62+
}
63+
64+
const h = (arg: LiteralsOrWeakTypes) => {
65+
>h : (arg: LiteralsOrWeakTypes) => LiteralsOrWeakTypes
66+
>(arg: LiteralsOrWeakTypes) => { if (arg === aOrB) { return arg; } else { return arg; }} : (arg: LiteralsOrWeakTypes) => LiteralsOrWeakTypes
67+
>arg : LiteralsOrWeakTypes
68+
69+
if (arg === aOrB) {
70+
>arg === aOrB : boolean
71+
>arg : LiteralsOrWeakTypes
72+
>aOrB : "A" | "B"
73+
74+
return arg;
75+
>arg : { toLowerCase?(): string; } | { toUpperCase?(): string; otherOptionalProp?: number | undefined; } | "A" | "B"
76+
}
77+
else {
78+
return arg;
79+
>arg : LiteralsOrWeakTypes
80+
}
81+
}
82+
83+
const i = (arg: WeakTypes) => {
84+
>i : (arg: WeakTypes) => WeakTypes
85+
>(arg: WeakTypes) => { if (arg === aOrB) { return arg; } else { return arg; }} : (arg: WeakTypes) => WeakTypes
86+
>arg : WeakTypes
87+
88+
if (arg === aOrB) {
89+
>arg === aOrB : boolean
90+
>arg : WeakTypes
91+
>aOrB : "A" | "B"
92+
93+
return arg;
94+
>arg : { toLowerCase?(): string; } | { toUpperCase?(): string; otherOptionalProp?: number | undefined; }
95+
}
96+
else {
97+
return arg;
98+
>arg : WeakTypes
99+
}
100+
}
101+
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
// @strict: true
2+
// @declaration: true
3+
// @emitDeclarationOnly: true
4+
5+
type WeakTypes =
6+
| { optional?: true; }
7+
| { toLowerCase?(): string }
8+
| { toUpperCase?(): string, otherOptionalProp?: number };
9+
10+
type LiteralsOrWeakTypes =
11+
| "A"
12+
| "B"
13+
| WeakTypes;
14+
15+
declare let aOrB: "A" | "B";
16+
17+
const f = (arg: LiteralsOrWeakTypes) => {
18+
if (arg === "A") {
19+
return arg;
20+
}
21+
else {
22+
return arg;
23+
}
24+
}
25+
26+
const g = (arg: WeakTypes) => {
27+
if (arg === "A") {
28+
return arg;
29+
}
30+
else {
31+
return arg;
32+
}
33+
}
34+
35+
const h = (arg: LiteralsOrWeakTypes) => {
36+
if (arg === aOrB) {
37+
return arg;
38+
}
39+
else {
40+
return arg;
41+
}
42+
}
43+
44+
const i = (arg: WeakTypes) => {
45+
if (arg === aOrB) {
46+
return arg;
47+
}
48+
else {
49+
return arg;
50+
}
51+
}

0 commit comments

Comments
 (0)