Skip to content

Commit c5b1011

Browse files
authoredFeb 8, 2022
Compute writeType from set accessors for union and intersection properties (#47674)
* Compute write type from set accessors for union and intersection properties * Add test for deferred writeType * Always check for writeType of symbol
1 parent 17b97cc commit c5b1011

17 files changed

+1105
-1
lines changed
 

Diff for: ‎src/compiler/checker.ts

+45-1
Original file line numberDiff line numberDiff line change
@@ -9696,6 +9696,41 @@ namespace ts {
96969696
return links.type;
96979697
}
96989698

9699+
function getWriteTypeOfSymbolWithDeferredType(symbol: Symbol): Type | undefined {
9700+
const links = getSymbolLinks(symbol);
9701+
if (!links.writeType && links.deferralWriteConstituents) {
9702+
Debug.assertIsDefined(links.deferralParent);
9703+
Debug.assertIsDefined(links.deferralConstituents);
9704+
links.writeType = links.deferralParent.flags & TypeFlags.Union ? getUnionType(links.deferralWriteConstituents) : getIntersectionType(links.deferralWriteConstituents);
9705+
}
9706+
return links.writeType;
9707+
}
9708+
9709+
/**
9710+
* Distinct write types come only from set accessors, but union and intersection
9711+
* properties deriving from set accessors will either pre-compute or defer the
9712+
* union or intersection of the writeTypes of their constituents. To account for
9713+
* this, we will assume that any deferred type or transient symbol may have a
9714+
* `writeType` (or a deferred write type ready to be computed) that should be
9715+
* used before looking for set accessor declarations.
9716+
*/
9717+
function getWriteTypeOfSymbol(symbol: Symbol): Type {
9718+
const checkFlags = getCheckFlags(symbol);
9719+
if (checkFlags & CheckFlags.DeferredType) {
9720+
const writeType = getWriteTypeOfSymbolWithDeferredType(symbol);
9721+
if (writeType) {
9722+
return writeType;
9723+
}
9724+
}
9725+
if (symbol.flags & SymbolFlags.Transient) {
9726+
const { writeType } = symbol as TransientSymbol;
9727+
if (writeType) {
9728+
return writeType;
9729+
}
9730+
}
9731+
return getSetAccessorTypeOfSymbol(symbol);
9732+
}
9733+
96999734
function getSetAccessorTypeOfSymbol(symbol: Symbol): Type {
97009735
if (symbol.flags & SymbolFlags.Accessor) {
97019736
const type = getTypeOfSetAccessor(symbol);
@@ -12198,6 +12233,7 @@ namespace ts {
1219812233
let firstType: Type | undefined;
1219912234
let nameType: Type | undefined;
1220012235
const propTypes: Type[] = [];
12236+
let writeTypes: Type[] | undefined;
1220112237
let firstValueDeclaration: Declaration | undefined;
1220212238
let hasNonUniformValueDeclaration = false;
1220312239
for (const prop of props) {
@@ -12213,6 +12249,10 @@ namespace ts {
1221312249
firstType = type;
1221412250
nameType = getSymbolLinks(prop).nameType;
1221512251
}
12252+
const writeType = getWriteTypeOfSymbol(prop);
12253+
if (writeTypes || writeType !== type) {
12254+
writeTypes = append(!writeTypes ? propTypes.slice() : writeTypes, writeType);
12255+
}
1221612256
else if (type !== firstType) {
1221712257
checkFlags |= CheckFlags.HasNonUniformType;
1221812258
}
@@ -12243,9 +12283,13 @@ namespace ts {
1224312283
result.checkFlags |= CheckFlags.DeferredType;
1224412284
result.deferralParent = containingType;
1224512285
result.deferralConstituents = propTypes;
12286+
result.deferralWriteConstituents = writeTypes;
1224612287
}
1224712288
else {
1224812289
result.type = isUnion ? getUnionType(propTypes) : getIntersectionType(propTypes);
12290+
if (writeTypes) {
12291+
result.writeType = isUnion ? getUnionType(writeTypes) : getIntersectionType(writeTypes);
12292+
}
1224912293
}
1225012294
return result;
1225112295
}
@@ -28509,7 +28553,7 @@ namespace ts {
2850928553
return errorType;
2851028554
}
2851128555

28512-
propType = isThisPropertyAccessInConstructor(node, prop) ? autoType : writing ? getSetAccessorTypeOfSymbol(prop) : getTypeOfSymbol(prop);
28556+
propType = isThisPropertyAccessInConstructor(node, prop) ? autoType : writing ? getWriteTypeOfSymbol(prop) : getTypeOfSymbol(prop);
2851328557
}
2851428558

2851528559
return getFlowTypeOfAccessExpression(node, prop, propType, right, checkMode);

Diff for: ‎src/compiler/types.ts

+1
Original file line numberDiff line numberDiff line change
@@ -4952,6 +4952,7 @@ namespace ts {
49524952
extendedContainersByFile?: ESMap<NodeId, Symbol[]>; // Containers (other than the parent) which this symbol is aliased in
49534953
variances?: VarianceFlags[]; // Alias symbol type argument variance cache
49544954
deferralConstituents?: Type[]; // Calculated list of constituents for a deferred type
4955+
deferralWriteConstituents?: Type[]; // Constituents of a deferred `writeType`
49554956
deferralParent?: Type; // Source union/intersection of a deferred type
49564957
cjsExportMerged?: Symbol; // Version of the symbol with all non export= exports merged with the export= target
49574958
typeOnlyDeclaration?: TypeOnlyAliasDeclaration | false; // First resolved alias declaration that makes the symbol only usable in type constructs

Diff for: ‎src/compiler/utilities.ts

+4
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,10 @@ namespace ts {
2020
return undefined;
2121
}
2222

23+
export function getDeclarationsOfKind<T extends Declaration>(symbol: Symbol, kind: T["kind"]): T[] {
24+
return filter(symbol.declarations || emptyArray, d => d.kind === kind) as T[];
25+
}
26+
2327
export function createSymbolTable(symbols?: readonly Symbol[]): SymbolTable {
2428
const result = new Map<__String, Symbol>();
2529
if (symbols) {
+108
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
//// [divergentAccessorsTypes3.ts]
2+
class One {
3+
get prop1(): string { return ""; }
4+
set prop1(s: string | number) { }
5+
6+
get prop2(): string { return ""; }
7+
set prop2(s: string | number) { }
8+
9+
prop3: number;
10+
11+
get prop4(): string { return ""; }
12+
set prop4(s: string | number) { }
13+
}
14+
15+
class Two {
16+
get prop1(): string { return ""; }
17+
set prop1(s: string | number) { }
18+
19+
get prop2(): string { return ""; }
20+
set prop2(s: string) { }
21+
22+
get prop3(): string { return ""; }
23+
set prop3(s: string | boolean) { }
24+
25+
get prop4(): string { return ""; }
26+
set prop4(s: string | boolean) { }
27+
}
28+
29+
declare const u1: One|Two;
30+
31+
u1.prop1 = 42;
32+
u1.prop1 = "hello";
33+
34+
u1.prop2 = 42;
35+
u1.prop2 = "hello";
36+
37+
u1.prop3 = 42;
38+
u1.prop3 = "hello";
39+
u1.prop3 = true;
40+
41+
u1.prop4 = 42;
42+
u1.prop4 = "hello";
43+
u1.prop4 = true;
44+
45+
46+
//// [divergentAccessorsTypes3.js]
47+
var One = /** @class */ (function () {
48+
function One() {
49+
}
50+
Object.defineProperty(One.prototype, "prop1", {
51+
get: function () { return ""; },
52+
set: function (s) { },
53+
enumerable: false,
54+
configurable: true
55+
});
56+
Object.defineProperty(One.prototype, "prop2", {
57+
get: function () { return ""; },
58+
set: function (s) { },
59+
enumerable: false,
60+
configurable: true
61+
});
62+
Object.defineProperty(One.prototype, "prop4", {
63+
get: function () { return ""; },
64+
set: function (s) { },
65+
enumerable: false,
66+
configurable: true
67+
});
68+
return One;
69+
}());
70+
var Two = /** @class */ (function () {
71+
function Two() {
72+
}
73+
Object.defineProperty(Two.prototype, "prop1", {
74+
get: function () { return ""; },
75+
set: function (s) { },
76+
enumerable: false,
77+
configurable: true
78+
});
79+
Object.defineProperty(Two.prototype, "prop2", {
80+
get: function () { return ""; },
81+
set: function (s) { },
82+
enumerable: false,
83+
configurable: true
84+
});
85+
Object.defineProperty(Two.prototype, "prop3", {
86+
get: function () { return ""; },
87+
set: function (s) { },
88+
enumerable: false,
89+
configurable: true
90+
});
91+
Object.defineProperty(Two.prototype, "prop4", {
92+
get: function () { return ""; },
93+
set: function (s) { },
94+
enumerable: false,
95+
configurable: true
96+
});
97+
return Two;
98+
}());
99+
u1.prop1 = 42;
100+
u1.prop1 = "hello";
101+
u1.prop2 = 42;
102+
u1.prop2 = "hello";
103+
u1.prop3 = 42;
104+
u1.prop3 = "hello";
105+
u1.prop3 = true;
106+
u1.prop4 = 42;
107+
u1.prop4 = "hello";
108+
u1.prop4 = true;
+116
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
=== tests/cases/compiler/divergentAccessorsTypes3.ts ===
2+
class One {
3+
>One : Symbol(One, Decl(divergentAccessorsTypes3.ts, 0, 0))
4+
5+
get prop1(): string { return ""; }
6+
>prop1 : Symbol(One.prop1, Decl(divergentAccessorsTypes3.ts, 0, 11), Decl(divergentAccessorsTypes3.ts, 1, 36))
7+
8+
set prop1(s: string | number) { }
9+
>prop1 : Symbol(One.prop1, Decl(divergentAccessorsTypes3.ts, 0, 11), Decl(divergentAccessorsTypes3.ts, 1, 36))
10+
>s : Symbol(s, Decl(divergentAccessorsTypes3.ts, 2, 12))
11+
12+
get prop2(): string { return ""; }
13+
>prop2 : Symbol(One.prop2, Decl(divergentAccessorsTypes3.ts, 2, 35), Decl(divergentAccessorsTypes3.ts, 4, 36))
14+
15+
set prop2(s: string | number) { }
16+
>prop2 : Symbol(One.prop2, Decl(divergentAccessorsTypes3.ts, 2, 35), Decl(divergentAccessorsTypes3.ts, 4, 36))
17+
>s : Symbol(s, Decl(divergentAccessorsTypes3.ts, 5, 12))
18+
19+
prop3: number;
20+
>prop3 : Symbol(One.prop3, Decl(divergentAccessorsTypes3.ts, 5, 35))
21+
22+
get prop4(): string { return ""; }
23+
>prop4 : Symbol(One.prop4, Decl(divergentAccessorsTypes3.ts, 7, 16), Decl(divergentAccessorsTypes3.ts, 9, 36))
24+
25+
set prop4(s: string | number) { }
26+
>prop4 : Symbol(One.prop4, Decl(divergentAccessorsTypes3.ts, 7, 16), Decl(divergentAccessorsTypes3.ts, 9, 36))
27+
>s : Symbol(s, Decl(divergentAccessorsTypes3.ts, 10, 12))
28+
}
29+
30+
class Two {
31+
>Two : Symbol(Two, Decl(divergentAccessorsTypes3.ts, 11, 1))
32+
33+
get prop1(): string { return ""; }
34+
>prop1 : Symbol(Two.prop1, Decl(divergentAccessorsTypes3.ts, 13, 11), Decl(divergentAccessorsTypes3.ts, 14, 36))
35+
36+
set prop1(s: string | number) { }
37+
>prop1 : Symbol(Two.prop1, Decl(divergentAccessorsTypes3.ts, 13, 11), Decl(divergentAccessorsTypes3.ts, 14, 36))
38+
>s : Symbol(s, Decl(divergentAccessorsTypes3.ts, 15, 12))
39+
40+
get prop2(): string { return ""; }
41+
>prop2 : Symbol(Two.prop2, Decl(divergentAccessorsTypes3.ts, 15, 35), Decl(divergentAccessorsTypes3.ts, 17, 36))
42+
43+
set prop2(s: string) { }
44+
>prop2 : Symbol(Two.prop2, Decl(divergentAccessorsTypes3.ts, 15, 35), Decl(divergentAccessorsTypes3.ts, 17, 36))
45+
>s : Symbol(s, Decl(divergentAccessorsTypes3.ts, 18, 12))
46+
47+
get prop3(): string { return ""; }
48+
>prop3 : Symbol(Two.prop3, Decl(divergentAccessorsTypes3.ts, 18, 26), Decl(divergentAccessorsTypes3.ts, 20, 36))
49+
50+
set prop3(s: string | boolean) { }
51+
>prop3 : Symbol(Two.prop3, Decl(divergentAccessorsTypes3.ts, 18, 26), Decl(divergentAccessorsTypes3.ts, 20, 36))
52+
>s : Symbol(s, Decl(divergentAccessorsTypes3.ts, 21, 12))
53+
54+
get prop4(): string { return ""; }
55+
>prop4 : Symbol(Two.prop4, Decl(divergentAccessorsTypes3.ts, 21, 36), Decl(divergentAccessorsTypes3.ts, 23, 36))
56+
57+
set prop4(s: string | boolean) { }
58+
>prop4 : Symbol(Two.prop4, Decl(divergentAccessorsTypes3.ts, 21, 36), Decl(divergentAccessorsTypes3.ts, 23, 36))
59+
>s : Symbol(s, Decl(divergentAccessorsTypes3.ts, 24, 12))
60+
}
61+
62+
declare const u1: One|Two;
63+
>u1 : Symbol(u1, Decl(divergentAccessorsTypes3.ts, 27, 13))
64+
>One : Symbol(One, Decl(divergentAccessorsTypes3.ts, 0, 0))
65+
>Two : Symbol(Two, Decl(divergentAccessorsTypes3.ts, 11, 1))
66+
67+
u1.prop1 = 42;
68+
>u1.prop1 : Symbol(prop1, Decl(divergentAccessorsTypes3.ts, 0, 11), Decl(divergentAccessorsTypes3.ts, 1, 36), Decl(divergentAccessorsTypes3.ts, 13, 11), Decl(divergentAccessorsTypes3.ts, 14, 36))
69+
>u1 : Symbol(u1, Decl(divergentAccessorsTypes3.ts, 27, 13))
70+
>prop1 : Symbol(prop1, Decl(divergentAccessorsTypes3.ts, 0, 11), Decl(divergentAccessorsTypes3.ts, 1, 36), Decl(divergentAccessorsTypes3.ts, 13, 11), Decl(divergentAccessorsTypes3.ts, 14, 36))
71+
72+
u1.prop1 = "hello";
73+
>u1.prop1 : Symbol(prop1, Decl(divergentAccessorsTypes3.ts, 0, 11), Decl(divergentAccessorsTypes3.ts, 1, 36), Decl(divergentAccessorsTypes3.ts, 13, 11), Decl(divergentAccessorsTypes3.ts, 14, 36))
74+
>u1 : Symbol(u1, Decl(divergentAccessorsTypes3.ts, 27, 13))
75+
>prop1 : Symbol(prop1, Decl(divergentAccessorsTypes3.ts, 0, 11), Decl(divergentAccessorsTypes3.ts, 1, 36), Decl(divergentAccessorsTypes3.ts, 13, 11), Decl(divergentAccessorsTypes3.ts, 14, 36))
76+
77+
u1.prop2 = 42;
78+
>u1.prop2 : Symbol(prop2, Decl(divergentAccessorsTypes3.ts, 2, 35), Decl(divergentAccessorsTypes3.ts, 4, 36), Decl(divergentAccessorsTypes3.ts, 15, 35), Decl(divergentAccessorsTypes3.ts, 17, 36))
79+
>u1 : Symbol(u1, Decl(divergentAccessorsTypes3.ts, 27, 13))
80+
>prop2 : Symbol(prop2, Decl(divergentAccessorsTypes3.ts, 2, 35), Decl(divergentAccessorsTypes3.ts, 4, 36), Decl(divergentAccessorsTypes3.ts, 15, 35), Decl(divergentAccessorsTypes3.ts, 17, 36))
81+
82+
u1.prop2 = "hello";
83+
>u1.prop2 : Symbol(prop2, Decl(divergentAccessorsTypes3.ts, 2, 35), Decl(divergentAccessorsTypes3.ts, 4, 36), Decl(divergentAccessorsTypes3.ts, 15, 35), Decl(divergentAccessorsTypes3.ts, 17, 36))
84+
>u1 : Symbol(u1, Decl(divergentAccessorsTypes3.ts, 27, 13))
85+
>prop2 : Symbol(prop2, Decl(divergentAccessorsTypes3.ts, 2, 35), Decl(divergentAccessorsTypes3.ts, 4, 36), Decl(divergentAccessorsTypes3.ts, 15, 35), Decl(divergentAccessorsTypes3.ts, 17, 36))
86+
87+
u1.prop3 = 42;
88+
>u1.prop3 : Symbol(prop3, Decl(divergentAccessorsTypes3.ts, 5, 35), Decl(divergentAccessorsTypes3.ts, 18, 26), Decl(divergentAccessorsTypes3.ts, 20, 36))
89+
>u1 : Symbol(u1, Decl(divergentAccessorsTypes3.ts, 27, 13))
90+
>prop3 : Symbol(prop3, Decl(divergentAccessorsTypes3.ts, 5, 35), Decl(divergentAccessorsTypes3.ts, 18, 26), Decl(divergentAccessorsTypes3.ts, 20, 36))
91+
92+
u1.prop3 = "hello";
93+
>u1.prop3 : Symbol(prop3, Decl(divergentAccessorsTypes3.ts, 5, 35), Decl(divergentAccessorsTypes3.ts, 18, 26), Decl(divergentAccessorsTypes3.ts, 20, 36))
94+
>u1 : Symbol(u1, Decl(divergentAccessorsTypes3.ts, 27, 13))
95+
>prop3 : Symbol(prop3, Decl(divergentAccessorsTypes3.ts, 5, 35), Decl(divergentAccessorsTypes3.ts, 18, 26), Decl(divergentAccessorsTypes3.ts, 20, 36))
96+
97+
u1.prop3 = true;
98+
>u1.prop3 : Symbol(prop3, Decl(divergentAccessorsTypes3.ts, 5, 35), Decl(divergentAccessorsTypes3.ts, 18, 26), Decl(divergentAccessorsTypes3.ts, 20, 36))
99+
>u1 : Symbol(u1, Decl(divergentAccessorsTypes3.ts, 27, 13))
100+
>prop3 : Symbol(prop3, Decl(divergentAccessorsTypes3.ts, 5, 35), Decl(divergentAccessorsTypes3.ts, 18, 26), Decl(divergentAccessorsTypes3.ts, 20, 36))
101+
102+
u1.prop4 = 42;
103+
>u1.prop4 : Symbol(prop4, Decl(divergentAccessorsTypes3.ts, 7, 16), Decl(divergentAccessorsTypes3.ts, 9, 36), Decl(divergentAccessorsTypes3.ts, 21, 36), Decl(divergentAccessorsTypes3.ts, 23, 36))
104+
>u1 : Symbol(u1, Decl(divergentAccessorsTypes3.ts, 27, 13))
105+
>prop4 : Symbol(prop4, Decl(divergentAccessorsTypes3.ts, 7, 16), Decl(divergentAccessorsTypes3.ts, 9, 36), Decl(divergentAccessorsTypes3.ts, 21, 36), Decl(divergentAccessorsTypes3.ts, 23, 36))
106+
107+
u1.prop4 = "hello";
108+
>u1.prop4 : Symbol(prop4, Decl(divergentAccessorsTypes3.ts, 7, 16), Decl(divergentAccessorsTypes3.ts, 9, 36), Decl(divergentAccessorsTypes3.ts, 21, 36), Decl(divergentAccessorsTypes3.ts, 23, 36))
109+
>u1 : Symbol(u1, Decl(divergentAccessorsTypes3.ts, 27, 13))
110+
>prop4 : Symbol(prop4, Decl(divergentAccessorsTypes3.ts, 7, 16), Decl(divergentAccessorsTypes3.ts, 9, 36), Decl(divergentAccessorsTypes3.ts, 21, 36), Decl(divergentAccessorsTypes3.ts, 23, 36))
111+
112+
u1.prop4 = true;
113+
>u1.prop4 : Symbol(prop4, Decl(divergentAccessorsTypes3.ts, 7, 16), Decl(divergentAccessorsTypes3.ts, 9, 36), Decl(divergentAccessorsTypes3.ts, 21, 36), Decl(divergentAccessorsTypes3.ts, 23, 36))
114+
>u1 : Symbol(u1, Decl(divergentAccessorsTypes3.ts, 27, 13))
115+
>prop4 : Symbol(prop4, Decl(divergentAccessorsTypes3.ts, 7, 16), Decl(divergentAccessorsTypes3.ts, 9, 36), Decl(divergentAccessorsTypes3.ts, 21, 36), Decl(divergentAccessorsTypes3.ts, 23, 36))
116+
+141
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
=== tests/cases/compiler/divergentAccessorsTypes3.ts ===
2+
class One {
3+
>One : One
4+
5+
get prop1(): string { return ""; }
6+
>prop1 : string
7+
>"" : ""
8+
9+
set prop1(s: string | number) { }
10+
>prop1 : string
11+
>s : string | number
12+
13+
get prop2(): string { return ""; }
14+
>prop2 : string
15+
>"" : ""
16+
17+
set prop2(s: string | number) { }
18+
>prop2 : string
19+
>s : string | number
20+
21+
prop3: number;
22+
>prop3 : number
23+
24+
get prop4(): string { return ""; }
25+
>prop4 : string
26+
>"" : ""
27+
28+
set prop4(s: string | number) { }
29+
>prop4 : string
30+
>s : string | number
31+
}
32+
33+
class Two {
34+
>Two : Two
35+
36+
get prop1(): string { return ""; }
37+
>prop1 : string
38+
>"" : ""
39+
40+
set prop1(s: string | number) { }
41+
>prop1 : string
42+
>s : string | number
43+
44+
get prop2(): string { return ""; }
45+
>prop2 : string
46+
>"" : ""
47+
48+
set prop2(s: string) { }
49+
>prop2 : string
50+
>s : string
51+
52+
get prop3(): string { return ""; }
53+
>prop3 : string
54+
>"" : ""
55+
56+
set prop3(s: string | boolean) { }
57+
>prop3 : string
58+
>s : string | boolean
59+
60+
get prop4(): string { return ""; }
61+
>prop4 : string
62+
>"" : ""
63+
64+
set prop4(s: string | boolean) { }
65+
>prop4 : string
66+
>s : string | boolean
67+
}
68+
69+
declare const u1: One|Two;
70+
>u1 : One | Two
71+
72+
u1.prop1 = 42;
73+
>u1.prop1 = 42 : 42
74+
>u1.prop1 : string | number
75+
>u1 : One | Two
76+
>prop1 : string | number
77+
>42 : 42
78+
79+
u1.prop1 = "hello";
80+
>u1.prop1 = "hello" : "hello"
81+
>u1.prop1 : string | number
82+
>u1 : One | Two
83+
>prop1 : string | number
84+
>"hello" : "hello"
85+
86+
u1.prop2 = 42;
87+
>u1.prop2 = 42 : 42
88+
>u1.prop2 : string | number
89+
>u1 : One | Two
90+
>prop2 : string | number
91+
>42 : 42
92+
93+
u1.prop2 = "hello";
94+
>u1.prop2 = "hello" : "hello"
95+
>u1.prop2 : string | number
96+
>u1 : One | Two
97+
>prop2 : string | number
98+
>"hello" : "hello"
99+
100+
u1.prop3 = 42;
101+
>u1.prop3 = 42 : 42
102+
>u1.prop3 : string | number | boolean
103+
>u1 : One | Two
104+
>prop3 : string | number | boolean
105+
>42 : 42
106+
107+
u1.prop3 = "hello";
108+
>u1.prop3 = "hello" : "hello"
109+
>u1.prop3 : string | number | boolean
110+
>u1 : One | Two
111+
>prop3 : string | number | boolean
112+
>"hello" : "hello"
113+
114+
u1.prop3 = true;
115+
>u1.prop3 = true : true
116+
>u1.prop3 : string | number | boolean
117+
>u1 : One | Two
118+
>prop3 : string | number | boolean
119+
>true : true
120+
121+
u1.prop4 = 42;
122+
>u1.prop4 = 42 : 42
123+
>u1.prop4 : string | number | boolean
124+
>u1 : One | Two
125+
>prop4 : string | number | boolean
126+
>42 : 42
127+
128+
u1.prop4 = "hello";
129+
>u1.prop4 = "hello" : "hello"
130+
>u1.prop4 : string | number | boolean
131+
>u1 : One | Two
132+
>prop4 : string | number | boolean
133+
>"hello" : "hello"
134+
135+
u1.prop4 = true;
136+
>u1.prop4 = true : true
137+
>u1.prop4 : string | number | boolean
138+
>u1 : One | Two
139+
>prop4 : string | number | boolean
140+
>true : true
141+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
tests/cases/compiler/divergentAccessorsTypes4.ts(29,1): error TS2322: Type '"hello"' is not assignable to type '42'.
2+
3+
4+
==== tests/cases/compiler/divergentAccessorsTypes4.ts (1 errors) ====
5+
class One {
6+
get prop1(): string { return ""; }
7+
set prop1(s: string | number) { }
8+
9+
prop2: number;
10+
}
11+
12+
class Two {
13+
get prop1(): "hello" { return "hello"; }
14+
set prop1(s: "hello" | number) { }
15+
16+
get prop2(): string { return ""; }
17+
set prop2(s: string | 42) { }
18+
19+
}
20+
21+
declare const i: One & Two;
22+
23+
// "hello"
24+
i.prop1;
25+
// number | "hello"
26+
i.prop1 = 42;
27+
i.prop1 = "hello";
28+
29+
// never
30+
i.prop2;
31+
// 42
32+
i.prop2 = 42;
33+
i.prop2 = "hello"; // error
34+
~~~~~~~
35+
!!! error TS2322: Type '"hello"' is not assignable to type '42'.
36+
+71
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
//// [divergentAccessorsTypes4.ts]
2+
class One {
3+
get prop1(): string { return ""; }
4+
set prop1(s: string | number) { }
5+
6+
prop2: number;
7+
}
8+
9+
class Two {
10+
get prop1(): "hello" { return "hello"; }
11+
set prop1(s: "hello" | number) { }
12+
13+
get prop2(): string { return ""; }
14+
set prop2(s: string | 42) { }
15+
16+
}
17+
18+
declare const i: One & Two;
19+
20+
// "hello"
21+
i.prop1;
22+
// number | "hello"
23+
i.prop1 = 42;
24+
i.prop1 = "hello";
25+
26+
// never
27+
i.prop2;
28+
// 42
29+
i.prop2 = 42;
30+
i.prop2 = "hello"; // error
31+
32+
33+
//// [divergentAccessorsTypes4.js]
34+
var One = /** @class */ (function () {
35+
function One() {
36+
}
37+
Object.defineProperty(One.prototype, "prop1", {
38+
get: function () { return ""; },
39+
set: function (s) { },
40+
enumerable: false,
41+
configurable: true
42+
});
43+
return One;
44+
}());
45+
var Two = /** @class */ (function () {
46+
function Two() {
47+
}
48+
Object.defineProperty(Two.prototype, "prop1", {
49+
get: function () { return "hello"; },
50+
set: function (s) { },
51+
enumerable: false,
52+
configurable: true
53+
});
54+
Object.defineProperty(Two.prototype, "prop2", {
55+
get: function () { return ""; },
56+
set: function (s) { },
57+
enumerable: false,
58+
configurable: true
59+
});
60+
return Two;
61+
}());
62+
// "hello"
63+
i.prop1;
64+
// number | "hello"
65+
i.prop1 = 42;
66+
i.prop1 = "hello";
67+
// never
68+
i.prop2;
69+
// 42
70+
i.prop2 = 42;
71+
i.prop2 = "hello"; // error
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
=== tests/cases/compiler/divergentAccessorsTypes4.ts ===
2+
class One {
3+
>One : Symbol(One, Decl(divergentAccessorsTypes4.ts, 0, 0))
4+
5+
get prop1(): string { return ""; }
6+
>prop1 : Symbol(One.prop1, Decl(divergentAccessorsTypes4.ts, 0, 11), Decl(divergentAccessorsTypes4.ts, 1, 36))
7+
8+
set prop1(s: string | number) { }
9+
>prop1 : Symbol(One.prop1, Decl(divergentAccessorsTypes4.ts, 0, 11), Decl(divergentAccessorsTypes4.ts, 1, 36))
10+
>s : Symbol(s, Decl(divergentAccessorsTypes4.ts, 2, 12))
11+
12+
prop2: number;
13+
>prop2 : Symbol(One.prop2, Decl(divergentAccessorsTypes4.ts, 2, 35))
14+
}
15+
16+
class Two {
17+
>Two : Symbol(Two, Decl(divergentAccessorsTypes4.ts, 5, 1))
18+
19+
get prop1(): "hello" { return "hello"; }
20+
>prop1 : Symbol(Two.prop1, Decl(divergentAccessorsTypes4.ts, 7, 11), Decl(divergentAccessorsTypes4.ts, 8, 42))
21+
22+
set prop1(s: "hello" | number) { }
23+
>prop1 : Symbol(Two.prop1, Decl(divergentAccessorsTypes4.ts, 7, 11), Decl(divergentAccessorsTypes4.ts, 8, 42))
24+
>s : Symbol(s, Decl(divergentAccessorsTypes4.ts, 9, 12))
25+
26+
get prop2(): string { return ""; }
27+
>prop2 : Symbol(Two.prop2, Decl(divergentAccessorsTypes4.ts, 9, 36), Decl(divergentAccessorsTypes4.ts, 11, 36))
28+
29+
set prop2(s: string | 42) { }
30+
>prop2 : Symbol(Two.prop2, Decl(divergentAccessorsTypes4.ts, 9, 36), Decl(divergentAccessorsTypes4.ts, 11, 36))
31+
>s : Symbol(s, Decl(divergentAccessorsTypes4.ts, 12, 12))
32+
33+
}
34+
35+
declare const i: One & Two;
36+
>i : Symbol(i, Decl(divergentAccessorsTypes4.ts, 16, 13))
37+
>One : Symbol(One, Decl(divergentAccessorsTypes4.ts, 0, 0))
38+
>Two : Symbol(Two, Decl(divergentAccessorsTypes4.ts, 5, 1))
39+
40+
// "hello"
41+
i.prop1;
42+
>i.prop1 : Symbol(prop1, Decl(divergentAccessorsTypes4.ts, 0, 11), Decl(divergentAccessorsTypes4.ts, 1, 36), Decl(divergentAccessorsTypes4.ts, 7, 11), Decl(divergentAccessorsTypes4.ts, 8, 42))
43+
>i : Symbol(i, Decl(divergentAccessorsTypes4.ts, 16, 13))
44+
>prop1 : Symbol(prop1, Decl(divergentAccessorsTypes4.ts, 0, 11), Decl(divergentAccessorsTypes4.ts, 1, 36), Decl(divergentAccessorsTypes4.ts, 7, 11), Decl(divergentAccessorsTypes4.ts, 8, 42))
45+
46+
// number | "hello"
47+
i.prop1 = 42;
48+
>i.prop1 : Symbol(prop1, Decl(divergentAccessorsTypes4.ts, 0, 11), Decl(divergentAccessorsTypes4.ts, 1, 36), Decl(divergentAccessorsTypes4.ts, 7, 11), Decl(divergentAccessorsTypes4.ts, 8, 42))
49+
>i : Symbol(i, Decl(divergentAccessorsTypes4.ts, 16, 13))
50+
>prop1 : Symbol(prop1, Decl(divergentAccessorsTypes4.ts, 0, 11), Decl(divergentAccessorsTypes4.ts, 1, 36), Decl(divergentAccessorsTypes4.ts, 7, 11), Decl(divergentAccessorsTypes4.ts, 8, 42))
51+
52+
i.prop1 = "hello";
53+
>i.prop1 : Symbol(prop1, Decl(divergentAccessorsTypes4.ts, 0, 11), Decl(divergentAccessorsTypes4.ts, 1, 36), Decl(divergentAccessorsTypes4.ts, 7, 11), Decl(divergentAccessorsTypes4.ts, 8, 42))
54+
>i : Symbol(i, Decl(divergentAccessorsTypes4.ts, 16, 13))
55+
>prop1 : Symbol(prop1, Decl(divergentAccessorsTypes4.ts, 0, 11), Decl(divergentAccessorsTypes4.ts, 1, 36), Decl(divergentAccessorsTypes4.ts, 7, 11), Decl(divergentAccessorsTypes4.ts, 8, 42))
56+
57+
// never
58+
i.prop2;
59+
>i.prop2 : Symbol(prop2, Decl(divergentAccessorsTypes4.ts, 2, 35), Decl(divergentAccessorsTypes4.ts, 9, 36), Decl(divergentAccessorsTypes4.ts, 11, 36))
60+
>i : Symbol(i, Decl(divergentAccessorsTypes4.ts, 16, 13))
61+
>prop2 : Symbol(prop2, Decl(divergentAccessorsTypes4.ts, 2, 35), Decl(divergentAccessorsTypes4.ts, 9, 36), Decl(divergentAccessorsTypes4.ts, 11, 36))
62+
63+
// 42
64+
i.prop2 = 42;
65+
>i.prop2 : Symbol(prop2, Decl(divergentAccessorsTypes4.ts, 2, 35), Decl(divergentAccessorsTypes4.ts, 9, 36), Decl(divergentAccessorsTypes4.ts, 11, 36))
66+
>i : Symbol(i, Decl(divergentAccessorsTypes4.ts, 16, 13))
67+
>prop2 : Symbol(prop2, Decl(divergentAccessorsTypes4.ts, 2, 35), Decl(divergentAccessorsTypes4.ts, 9, 36), Decl(divergentAccessorsTypes4.ts, 11, 36))
68+
69+
i.prop2 = "hello"; // error
70+
>i.prop2 : Symbol(prop2, Decl(divergentAccessorsTypes4.ts, 2, 35), Decl(divergentAccessorsTypes4.ts, 9, 36), Decl(divergentAccessorsTypes4.ts, 11, 36))
71+
>i : Symbol(i, Decl(divergentAccessorsTypes4.ts, 16, 13))
72+
>prop2 : Symbol(prop2, Decl(divergentAccessorsTypes4.ts, 2, 35), Decl(divergentAccessorsTypes4.ts, 9, 36), Decl(divergentAccessorsTypes4.ts, 11, 36))
73+
+82
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
=== tests/cases/compiler/divergentAccessorsTypes4.ts ===
2+
class One {
3+
>One : One
4+
5+
get prop1(): string { return ""; }
6+
>prop1 : string
7+
>"" : ""
8+
9+
set prop1(s: string | number) { }
10+
>prop1 : string
11+
>s : string | number
12+
13+
prop2: number;
14+
>prop2 : number
15+
}
16+
17+
class Two {
18+
>Two : Two
19+
20+
get prop1(): "hello" { return "hello"; }
21+
>prop1 : "hello"
22+
>"hello" : "hello"
23+
24+
set prop1(s: "hello" | number) { }
25+
>prop1 : "hello"
26+
>s : number | "hello"
27+
28+
get prop2(): string { return ""; }
29+
>prop2 : string
30+
>"" : ""
31+
32+
set prop2(s: string | 42) { }
33+
>prop2 : string
34+
>s : string | 42
35+
36+
}
37+
38+
declare const i: One & Two;
39+
>i : One & Two
40+
41+
// "hello"
42+
i.prop1;
43+
>i.prop1 : "hello"
44+
>i : One & Two
45+
>prop1 : "hello"
46+
47+
// number | "hello"
48+
i.prop1 = 42;
49+
>i.prop1 = 42 : 42
50+
>i.prop1 : number | "hello"
51+
>i : One & Two
52+
>prop1 : number | "hello"
53+
>42 : 42
54+
55+
i.prop1 = "hello";
56+
>i.prop1 = "hello" : "hello"
57+
>i.prop1 : number | "hello"
58+
>i : One & Two
59+
>prop1 : number | "hello"
60+
>"hello" : "hello"
61+
62+
// never
63+
i.prop2;
64+
>i.prop2 : never
65+
>i : One & Two
66+
>prop2 : never
67+
68+
// 42
69+
i.prop2 = 42;
70+
>i.prop2 = 42 : 42
71+
>i.prop2 : 42
72+
>i : One & Two
73+
>prop2 : 42
74+
>42 : 42
75+
76+
i.prop2 = "hello"; // error
77+
>i.prop2 = "hello" : "hello"
78+
>i.prop2 : 42
79+
>i : One & Two
80+
>prop2 : 42
81+
>"hello" : "hello"
82+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
tests/cases/compiler/divergentAccessorsTypes5.ts(31,1): error TS2322: Type '42' is not assignable to type '"hello"'.
2+
tests/cases/compiler/divergentAccessorsTypes5.ts(36,1): error TS2322: Type '"hello"' is not assignable to type '42'.
3+
4+
5+
==== tests/cases/compiler/divergentAccessorsTypes5.ts (2 errors) ====
6+
// Not really different from divergentAccessorsTypes4.ts,
7+
// but goes through the deferred type code
8+
9+
class One {
10+
get prop1(): string { return ""; }
11+
set prop1(s: string | number) { }
12+
13+
prop2: number;
14+
}
15+
16+
class Two {
17+
get prop1(): "hello" { return "hello"; }
18+
set prop1(s: "hello" | number) { }
19+
20+
get prop2(): string { return ""; }
21+
set prop2(s: string | 42) { }
22+
23+
}
24+
25+
class Three {
26+
get prop1(): "hello" { return "hello"; }
27+
set prop1(s: "hello" | boolean) { }
28+
29+
get prop2(): string { return ""; }
30+
set prop2(s: string | number | boolean) { }
31+
}
32+
33+
declare const i: One & Two & Three;
34+
35+
// "hello"
36+
i.prop1 = 42; // error
37+
~~~~~~~
38+
!!! error TS2322: Type '42' is not assignable to type '"hello"'.
39+
i.prop1 = "hello";
40+
41+
// 42
42+
i.prop2 = 42;
43+
i.prop2 = "hello"; // error
44+
~~~~~~~
45+
!!! error TS2322: Type '"hello"' is not assignable to type '42'.
46+
+93
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
//// [divergentAccessorsTypes5.ts]
2+
// Not really different from divergentAccessorsTypes4.ts,
3+
// but goes through the deferred type code
4+
5+
class One {
6+
get prop1(): string { return ""; }
7+
set prop1(s: string | number) { }
8+
9+
prop2: number;
10+
}
11+
12+
class Two {
13+
get prop1(): "hello" { return "hello"; }
14+
set prop1(s: "hello" | number) { }
15+
16+
get prop2(): string { return ""; }
17+
set prop2(s: string | 42) { }
18+
19+
}
20+
21+
class Three {
22+
get prop1(): "hello" { return "hello"; }
23+
set prop1(s: "hello" | boolean) { }
24+
25+
get prop2(): string { return ""; }
26+
set prop2(s: string | number | boolean) { }
27+
}
28+
29+
declare const i: One & Two & Three;
30+
31+
// "hello"
32+
i.prop1 = 42; // error
33+
i.prop1 = "hello";
34+
35+
// 42
36+
i.prop2 = 42;
37+
i.prop2 = "hello"; // error
38+
39+
40+
//// [divergentAccessorsTypes5.js]
41+
// Not really different from divergentAccessorsTypes4.ts,
42+
// but goes through the deferred type code
43+
var One = /** @class */ (function () {
44+
function One() {
45+
}
46+
Object.defineProperty(One.prototype, "prop1", {
47+
get: function () { return ""; },
48+
set: function (s) { },
49+
enumerable: false,
50+
configurable: true
51+
});
52+
return One;
53+
}());
54+
var Two = /** @class */ (function () {
55+
function Two() {
56+
}
57+
Object.defineProperty(Two.prototype, "prop1", {
58+
get: function () { return "hello"; },
59+
set: function (s) { },
60+
enumerable: false,
61+
configurable: true
62+
});
63+
Object.defineProperty(Two.prototype, "prop2", {
64+
get: function () { return ""; },
65+
set: function (s) { },
66+
enumerable: false,
67+
configurable: true
68+
});
69+
return Two;
70+
}());
71+
var Three = /** @class */ (function () {
72+
function Three() {
73+
}
74+
Object.defineProperty(Three.prototype, "prop1", {
75+
get: function () { return "hello"; },
76+
set: function (s) { },
77+
enumerable: false,
78+
configurable: true
79+
});
80+
Object.defineProperty(Three.prototype, "prop2", {
81+
get: function () { return ""; },
82+
set: function (s) { },
83+
enumerable: false,
84+
configurable: true
85+
});
86+
return Three;
87+
}());
88+
// "hello"
89+
i.prop1 = 42; // error
90+
i.prop1 = "hello";
91+
// 42
92+
i.prop2 = 42;
93+
i.prop2 = "hello"; // error
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
=== tests/cases/compiler/divergentAccessorsTypes5.ts ===
2+
// Not really different from divergentAccessorsTypes4.ts,
3+
// but goes through the deferred type code
4+
5+
class One {
6+
>One : Symbol(One, Decl(divergentAccessorsTypes5.ts, 0, 0))
7+
8+
get prop1(): string { return ""; }
9+
>prop1 : Symbol(One.prop1, Decl(divergentAccessorsTypes5.ts, 3, 11), Decl(divergentAccessorsTypes5.ts, 4, 36))
10+
11+
set prop1(s: string | number) { }
12+
>prop1 : Symbol(One.prop1, Decl(divergentAccessorsTypes5.ts, 3, 11), Decl(divergentAccessorsTypes5.ts, 4, 36))
13+
>s : Symbol(s, Decl(divergentAccessorsTypes5.ts, 5, 12))
14+
15+
prop2: number;
16+
>prop2 : Symbol(One.prop2, Decl(divergentAccessorsTypes5.ts, 5, 35))
17+
}
18+
19+
class Two {
20+
>Two : Symbol(Two, Decl(divergentAccessorsTypes5.ts, 8, 1))
21+
22+
get prop1(): "hello" { return "hello"; }
23+
>prop1 : Symbol(Two.prop1, Decl(divergentAccessorsTypes5.ts, 10, 11), Decl(divergentAccessorsTypes5.ts, 11, 42))
24+
25+
set prop1(s: "hello" | number) { }
26+
>prop1 : Symbol(Two.prop1, Decl(divergentAccessorsTypes5.ts, 10, 11), Decl(divergentAccessorsTypes5.ts, 11, 42))
27+
>s : Symbol(s, Decl(divergentAccessorsTypes5.ts, 12, 12))
28+
29+
get prop2(): string { return ""; }
30+
>prop2 : Symbol(Two.prop2, Decl(divergentAccessorsTypes5.ts, 12, 36), Decl(divergentAccessorsTypes5.ts, 14, 36))
31+
32+
set prop2(s: string | 42) { }
33+
>prop2 : Symbol(Two.prop2, Decl(divergentAccessorsTypes5.ts, 12, 36), Decl(divergentAccessorsTypes5.ts, 14, 36))
34+
>s : Symbol(s, Decl(divergentAccessorsTypes5.ts, 15, 12))
35+
36+
}
37+
38+
class Three {
39+
>Three : Symbol(Three, Decl(divergentAccessorsTypes5.ts, 17, 1))
40+
41+
get prop1(): "hello" { return "hello"; }
42+
>prop1 : Symbol(Three.prop1, Decl(divergentAccessorsTypes5.ts, 19, 13), Decl(divergentAccessorsTypes5.ts, 20, 42))
43+
44+
set prop1(s: "hello" | boolean) { }
45+
>prop1 : Symbol(Three.prop1, Decl(divergentAccessorsTypes5.ts, 19, 13), Decl(divergentAccessorsTypes5.ts, 20, 42))
46+
>s : Symbol(s, Decl(divergentAccessorsTypes5.ts, 21, 12))
47+
48+
get prop2(): string { return ""; }
49+
>prop2 : Symbol(Three.prop2, Decl(divergentAccessorsTypes5.ts, 21, 37), Decl(divergentAccessorsTypes5.ts, 23, 36))
50+
51+
set prop2(s: string | number | boolean) { }
52+
>prop2 : Symbol(Three.prop2, Decl(divergentAccessorsTypes5.ts, 21, 37), Decl(divergentAccessorsTypes5.ts, 23, 36))
53+
>s : Symbol(s, Decl(divergentAccessorsTypes5.ts, 24, 12))
54+
}
55+
56+
declare const i: One & Two & Three;
57+
>i : Symbol(i, Decl(divergentAccessorsTypes5.ts, 27, 13))
58+
>One : Symbol(One, Decl(divergentAccessorsTypes5.ts, 0, 0))
59+
>Two : Symbol(Two, Decl(divergentAccessorsTypes5.ts, 8, 1))
60+
>Three : Symbol(Three, Decl(divergentAccessorsTypes5.ts, 17, 1))
61+
62+
// "hello"
63+
i.prop1 = 42; // error
64+
>i.prop1 : Symbol(prop1, Decl(divergentAccessorsTypes5.ts, 3, 11), Decl(divergentAccessorsTypes5.ts, 4, 36), Decl(divergentAccessorsTypes5.ts, 10, 11), Decl(divergentAccessorsTypes5.ts, 11, 42), Decl(divergentAccessorsTypes5.ts, 19, 13) ... and 1 more)
65+
>i : Symbol(i, Decl(divergentAccessorsTypes5.ts, 27, 13))
66+
>prop1 : Symbol(prop1, Decl(divergentAccessorsTypes5.ts, 3, 11), Decl(divergentAccessorsTypes5.ts, 4, 36), Decl(divergentAccessorsTypes5.ts, 10, 11), Decl(divergentAccessorsTypes5.ts, 11, 42), Decl(divergentAccessorsTypes5.ts, 19, 13) ... and 1 more)
67+
68+
i.prop1 = "hello";
69+
>i.prop1 : Symbol(prop1, Decl(divergentAccessorsTypes5.ts, 3, 11), Decl(divergentAccessorsTypes5.ts, 4, 36), Decl(divergentAccessorsTypes5.ts, 10, 11), Decl(divergentAccessorsTypes5.ts, 11, 42), Decl(divergentAccessorsTypes5.ts, 19, 13) ... and 1 more)
70+
>i : Symbol(i, Decl(divergentAccessorsTypes5.ts, 27, 13))
71+
>prop1 : Symbol(prop1, Decl(divergentAccessorsTypes5.ts, 3, 11), Decl(divergentAccessorsTypes5.ts, 4, 36), Decl(divergentAccessorsTypes5.ts, 10, 11), Decl(divergentAccessorsTypes5.ts, 11, 42), Decl(divergentAccessorsTypes5.ts, 19, 13) ... and 1 more)
72+
73+
// 42
74+
i.prop2 = 42;
75+
>i.prop2 : Symbol(prop2, Decl(divergentAccessorsTypes5.ts, 5, 35), Decl(divergentAccessorsTypes5.ts, 12, 36), Decl(divergentAccessorsTypes5.ts, 14, 36), Decl(divergentAccessorsTypes5.ts, 21, 37), Decl(divergentAccessorsTypes5.ts, 23, 36))
76+
>i : Symbol(i, Decl(divergentAccessorsTypes5.ts, 27, 13))
77+
>prop2 : Symbol(prop2, Decl(divergentAccessorsTypes5.ts, 5, 35), Decl(divergentAccessorsTypes5.ts, 12, 36), Decl(divergentAccessorsTypes5.ts, 14, 36), Decl(divergentAccessorsTypes5.ts, 21, 37), Decl(divergentAccessorsTypes5.ts, 23, 36))
78+
79+
i.prop2 = "hello"; // error
80+
>i.prop2 : Symbol(prop2, Decl(divergentAccessorsTypes5.ts, 5, 35), Decl(divergentAccessorsTypes5.ts, 12, 36), Decl(divergentAccessorsTypes5.ts, 14, 36), Decl(divergentAccessorsTypes5.ts, 21, 37), Decl(divergentAccessorsTypes5.ts, 23, 36))
81+
>i : Symbol(i, Decl(divergentAccessorsTypes5.ts, 27, 13))
82+
>prop2 : Symbol(prop2, Decl(divergentAccessorsTypes5.ts, 5, 35), Decl(divergentAccessorsTypes5.ts, 12, 36), Decl(divergentAccessorsTypes5.ts, 14, 36), Decl(divergentAccessorsTypes5.ts, 21, 37), Decl(divergentAccessorsTypes5.ts, 23, 36))
83+
+93
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
=== tests/cases/compiler/divergentAccessorsTypes5.ts ===
2+
// Not really different from divergentAccessorsTypes4.ts,
3+
// but goes through the deferred type code
4+
5+
class One {
6+
>One : One
7+
8+
get prop1(): string { return ""; }
9+
>prop1 : string
10+
>"" : ""
11+
12+
set prop1(s: string | number) { }
13+
>prop1 : string
14+
>s : string | number
15+
16+
prop2: number;
17+
>prop2 : number
18+
}
19+
20+
class Two {
21+
>Two : Two
22+
23+
get prop1(): "hello" { return "hello"; }
24+
>prop1 : "hello"
25+
>"hello" : "hello"
26+
27+
set prop1(s: "hello" | number) { }
28+
>prop1 : "hello"
29+
>s : number | "hello"
30+
31+
get prop2(): string { return ""; }
32+
>prop2 : string
33+
>"" : ""
34+
35+
set prop2(s: string | 42) { }
36+
>prop2 : string
37+
>s : string | 42
38+
39+
}
40+
41+
class Three {
42+
>Three : Three
43+
44+
get prop1(): "hello" { return "hello"; }
45+
>prop1 : "hello"
46+
>"hello" : "hello"
47+
48+
set prop1(s: "hello" | boolean) { }
49+
>prop1 : "hello"
50+
>s : boolean | "hello"
51+
52+
get prop2(): string { return ""; }
53+
>prop2 : string
54+
>"" : ""
55+
56+
set prop2(s: string | number | boolean) { }
57+
>prop2 : string
58+
>s : string | number | boolean
59+
}
60+
61+
declare const i: One & Two & Three;
62+
>i : One & Two & Three
63+
64+
// "hello"
65+
i.prop1 = 42; // error
66+
>i.prop1 = 42 : 42
67+
>i.prop1 : "hello"
68+
>i : One & Two & Three
69+
>prop1 : "hello"
70+
>42 : 42
71+
72+
i.prop1 = "hello";
73+
>i.prop1 = "hello" : "hello"
74+
>i.prop1 : "hello"
75+
>i : One & Two & Three
76+
>prop1 : "hello"
77+
>"hello" : "hello"
78+
79+
// 42
80+
i.prop2 = 42;
81+
>i.prop2 = 42 : 42
82+
>i.prop2 : 42
83+
>i : One & Two & Three
84+
>prop2 : 42
85+
>42 : 42
86+
87+
i.prop2 = "hello"; // error
88+
>i.prop2 = "hello" : "hello"
89+
>i.prop2 : 42
90+
>i : One & Two & Three
91+
>prop2 : 42
92+
>"hello" : "hello"
93+

Diff for: ‎tests/cases/compiler/divergentAccessorsTypes3.ts

+44
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
// @target: es5
2+
3+
class One {
4+
get prop1(): string { return ""; }
5+
set prop1(s: string | number) { }
6+
7+
get prop2(): string { return ""; }
8+
set prop2(s: string | number) { }
9+
10+
prop3: number;
11+
12+
get prop4(): string { return ""; }
13+
set prop4(s: string | number) { }
14+
}
15+
16+
class Two {
17+
get prop1(): string { return ""; }
18+
set prop1(s: string | number) { }
19+
20+
get prop2(): string { return ""; }
21+
set prop2(s: string) { }
22+
23+
get prop3(): string { return ""; }
24+
set prop3(s: string | boolean) { }
25+
26+
get prop4(): string { return ""; }
27+
set prop4(s: string | boolean) { }
28+
}
29+
30+
declare const u1: One|Two;
31+
32+
u1.prop1 = 42;
33+
u1.prop1 = "hello";
34+
35+
u1.prop2 = 42;
36+
u1.prop2 = "hello";
37+
38+
u1.prop3 = 42;
39+
u1.prop3 = "hello";
40+
u1.prop3 = true;
41+
42+
u1.prop4 = 42;
43+
u1.prop4 = "hello";
44+
u1.prop4 = true;

Diff for: ‎tests/cases/compiler/divergentAccessorsTypes4.ts

+31
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
// @target: es5
2+
3+
class One {
4+
get prop1(): string { return ""; }
5+
set prop1(s: string | number) { }
6+
7+
prop2: number;
8+
}
9+
10+
class Two {
11+
get prop1(): "hello" { return "hello"; }
12+
set prop1(s: "hello" | number) { }
13+
14+
get prop2(): string { return ""; }
15+
set prop2(s: string | 42) { }
16+
17+
}
18+
19+
declare const i: One & Two;
20+
21+
// "hello"
22+
i.prop1;
23+
// number | "hello"
24+
i.prop1 = 42;
25+
i.prop1 = "hello";
26+
27+
// never
28+
i.prop2;
29+
// 42
30+
i.prop2 = 42;
31+
i.prop2 = "hello"; // error

Diff for: ‎tests/cases/compiler/divergentAccessorsTypes5.ts

+38
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
// @target: es5
2+
3+
// Not really different from divergentAccessorsTypes4.ts,
4+
// but goes through the deferred type code
5+
6+
class One {
7+
get prop1(): string { return ""; }
8+
set prop1(s: string | number) { }
9+
10+
prop2: number;
11+
}
12+
13+
class Two {
14+
get prop1(): "hello" { return "hello"; }
15+
set prop1(s: "hello" | number) { }
16+
17+
get prop2(): string { return ""; }
18+
set prop2(s: string | 42) { }
19+
20+
}
21+
22+
class Three {
23+
get prop1(): "hello" { return "hello"; }
24+
set prop1(s: "hello" | boolean) { }
25+
26+
get prop2(): string { return ""; }
27+
set prop2(s: string | number | boolean) { }
28+
}
29+
30+
declare const i: One & Two & Three;
31+
32+
// "hello"
33+
i.prop1 = 42; // error
34+
i.prop1 = "hello";
35+
36+
// 42
37+
i.prop2 = 42;
38+
i.prop2 = "hello"; // error

0 commit comments

Comments
 (0)
Please sign in to comment.