Skip to content

Commit c080324

Browse files
authored
Elt access assignment uses declared, not narrowed type (microsoft#27574)
I forgot to do this in microsoft#26424. Fixes microsoft#27557 Fixes microsoft#27412
1 parent e1d346e commit c080324

8 files changed

+108
-7
lines changed

src/compiler/checker.ts

+3-1
Original file line numberDiff line numberDiff line change
@@ -9305,7 +9305,9 @@ namespace ts {
93059305
}
93069306
}
93079307
const propType = getTypeOfSymbol(prop);
9308-
return accessExpression ? getFlowTypeOfReference(accessExpression, propType) : propType;
9308+
return accessExpression && getAssignmentTargetKind(accessExpression) !== AssignmentKind.Definite ?
9309+
getFlowTypeOfReference(accessExpression, propType) :
9310+
propType;
93099311
}
93109312
if (isTupleType(objectType)) {
93119313
const restType = getRestTypeOfTupleType(objectType);

tests/baselines/reference/checkJsxChildrenCanBeTupleType.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ var __extends = (this && this.__extends) || (function () {
3030
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
3131
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
3232
return extendStatics(d, b);
33-
}
33+
};
3434
return function (d, b) {
3535
extendStatics(d, b);
3636
function __() { this.constructor = d; }
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
//// [controlFlowElementAccess.ts]
2+
let x: { o: boolean } = { o: false }
3+
if (x['o'] === false) {
4+
x['o'] = true
5+
}
6+
7+
const y: [number, number] = [0, 0];
8+
if (y[0] === 0) {
9+
y[0] = -1;
10+
}
11+
12+
13+
//// [controlFlowElementAccess.js]
14+
var x = { o: false };
15+
if (x['o'] === false) {
16+
x['o'] = true;
17+
}
18+
var y = [0, 0];
19+
if (y[0] === 0) {
20+
y[0] = -1;
21+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
=== tests/cases/conformance/controlFlow/controlFlowElementAccess.ts ===
2+
let x: { o: boolean } = { o: false }
3+
>x : Symbol(x, Decl(controlFlowElementAccess.ts, 0, 3))
4+
>o : Symbol(o, Decl(controlFlowElementAccess.ts, 0, 8))
5+
>o : Symbol(o, Decl(controlFlowElementAccess.ts, 0, 25))
6+
7+
if (x['o'] === false) {
8+
>x : Symbol(x, Decl(controlFlowElementAccess.ts, 0, 3))
9+
>'o' : Symbol(o, Decl(controlFlowElementAccess.ts, 0, 8))
10+
11+
x['o'] = true
12+
>x : Symbol(x, Decl(controlFlowElementAccess.ts, 0, 3))
13+
>'o' : Symbol(o, Decl(controlFlowElementAccess.ts, 0, 8))
14+
}
15+
16+
const y: [number, number] = [0, 0];
17+
>y : Symbol(y, Decl(controlFlowElementAccess.ts, 5, 5))
18+
19+
if (y[0] === 0) {
20+
>y : Symbol(y, Decl(controlFlowElementAccess.ts, 5, 5))
21+
>0 : Symbol(0)
22+
23+
y[0] = -1;
24+
>y : Symbol(y, Decl(controlFlowElementAccess.ts, 5, 5))
25+
>0 : Symbol(0)
26+
}
27+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
=== tests/cases/conformance/controlFlow/controlFlowElementAccess.ts ===
2+
let x: { o: boolean } = { o: false }
3+
>x : { o: boolean; }
4+
>o : boolean
5+
>{ o: false } : { o: false; }
6+
>o : false
7+
>false : false
8+
9+
if (x['o'] === false) {
10+
>x['o'] === false : boolean
11+
>x['o'] : boolean
12+
>x : { o: boolean; }
13+
>'o' : "o"
14+
>false : false
15+
16+
x['o'] = true
17+
>x['o'] = true : true
18+
>x['o'] : boolean
19+
>x : { o: boolean; }
20+
>'o' : "o"
21+
>true : true
22+
}
23+
24+
const y: [number, number] = [0, 0];
25+
>y : [number, number]
26+
>[0, 0] : [number, number]
27+
>0 : 0
28+
>0 : 0
29+
30+
if (y[0] === 0) {
31+
>y[0] === 0 : boolean
32+
>y[0] : number
33+
>y : [number, number]
34+
>0 : 0
35+
>0 : 0
36+
37+
y[0] = -1;
38+
>y[0] = -1 : -1
39+
>y[0] : number
40+
>y : [number, number]
41+
>0 : 0
42+
>-1 : -1
43+
>1 : 1
44+
}
45+

tests/baselines/reference/unionTypeWithIndexSignature.errors.txt

+1-4
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,12 @@
11
tests/cases/conformance/types/union/unionTypeWithIndexSignature.ts(11,3): error TS2339: Property 'bar' does not exist on type 'Missing'.
22
Property 'bar' does not exist on type '{ [s: string]: string; }'.
33
tests/cases/conformance/types/union/unionTypeWithIndexSignature.ts(14,4): error TS2540: Cannot assign to 'foo' because it is a constant or a read-only property.
4-
tests/cases/conformance/types/union/unionTypeWithIndexSignature.ts(18,1): error TS2322: Type '"ok"' is not assignable to type 'number'.
54
tests/cases/conformance/types/union/unionTypeWithIndexSignature.ts(24,1): error TS7017: Element implicitly has an 'any' type because type 'Both' has no index signature.
65
tests/cases/conformance/types/union/unionTypeWithIndexSignature.ts(25,1): error TS2322: Type '"not ok"' is not assignable to type 'number'.
76
tests/cases/conformance/types/union/unionTypeWithIndexSignature.ts(26,1): error TS7017: Element implicitly has an 'any' type because type 'Both' has no index signature.
87

98

10-
==== tests/cases/conformance/types/union/unionTypeWithIndexSignature.ts (6 errors) ====
9+
==== tests/cases/conformance/types/union/unionTypeWithIndexSignature.ts (5 errors) ====
1110
type Two = { foo: { bar: true }, baz: true } | { [s: string]: string };
1211
declare var u: Two
1312
u.foo = 'bye'
@@ -31,8 +30,6 @@ tests/cases/conformance/types/union/unionTypeWithIndexSignature.ts(26,1): error
3130
declare var num: Num
3231
num[0] = 1
3332
num['0'] = 'ok'
34-
~~~~~~~~
35-
!!! error TS2322: Type '"ok"' is not assignable to type 'number'.
3633
const sym = Symbol()
3734
type Both = { s: number, '0': number, [sym]: boolean } | { [n: number]: number, [s: string]: string | number }
3835
declare var both: Both

tests/baselines/reference/unionTypeWithIndexSignature.types

+1-1
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ num[0] = 1
9696

9797
num['0'] = 'ok'
9898
>num['0'] = 'ok' : "ok"
99-
>num['0'] : number
99+
>num['0'] : string | number
100100
>num : Num
101101
>'0' : "0"
102102
>'ok' : "ok"
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
let x: { o: boolean } = { o: false }
2+
if (x['o'] === false) {
3+
x['o'] = true
4+
}
5+
6+
const y: [number, number] = [0, 0];
7+
if (y[0] === 0) {
8+
y[0] = -1;
9+
}

0 commit comments

Comments
 (0)