Skip to content

Commit 2964f64

Browse files
committed
Fixed accidental undefined omissions in union props sourced from index type under noUncheckedIndexedAccess
1 parent 3f416e0 commit 2964f64

File tree

4 files changed

+163
-2
lines changed

4 files changed

+163
-2
lines changed

src/compiler/checker.ts

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15034,6 +15034,9 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
1503415034
propTypes.push(type);
1503515035
}
1503615036
addRange(propTypes, indexTypes);
15037+
if (indexTypes && compilerOptions.noUncheckedIndexedAccess) {
15038+
append(propTypes, missingType);
15039+
}
1503715040
const result = createSymbol(SymbolFlags.Property | (optionalFlag ?? 0), name, syntheticFlag | checkFlags);
1503815041
result.links.containingType = containingType;
1503915042
if (!hasNonUniformValueDeclaration && firstValueDeclaration) {
@@ -27576,6 +27579,8 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
2757627579
errorType;
2757727580
}
2757827581

27582+
function includeUndefinedInIndexSignature(type: Type): Type;
27583+
function includeUndefinedInIndexSignature(type: Type | undefined): Type | undefined;
2757927584
function includeUndefinedInIndexSignature(type: Type | undefined): Type | undefined {
2758027585
if (!type) return type;
2758127586
return compilerOptions.noUncheckedIndexedAccess ?
@@ -34193,8 +34198,8 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
3419334198
}
3419434199

3419534200
propType = indexInfo.type;
34196-
if (compilerOptions.noUncheckedIndexedAccess && getAssignmentTargetKind(node) !== AssignmentKind.Definite) {
34197-
propType = getUnionType([propType, missingType]);
34201+
if (getAssignmentTargetKind(node) !== AssignmentKind.Definite) {
34202+
propType = includeUndefinedInIndexSignature(propType)
3419834203
}
3419934204
if (compilerOptions.noPropertyAccessFromIndexSignature && isPropertyAccessExpression(node)) {
3420034205
error(right, Diagnostics.Property_0_comes_from_an_index_signature_so_it_must_be_accessed_with_0, unescapeLeadingUnderscores(right.escapedText));
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
//// [tests/cases/compiler/noUncheckedIndexAccessUnionProp1.ts] ////
2+
3+
=== noUncheckedIndexAccessUnionProp1.ts ===
4+
// https://github.com/microsoft/TypeScript/issues/61225
5+
6+
const nums: { [k: string]: number } = Math.random() < 0.5 ? { a: 1 } : { b: 2 };
7+
>nums : Symbol(nums, Decl(noUncheckedIndexAccessUnionProp1.ts, 2, 5))
8+
>k : Symbol(k, Decl(noUncheckedIndexAccessUnionProp1.ts, 2, 15))
9+
>Math.random : Symbol(Math.random, Decl(lib.es5.d.ts, --, --))
10+
>Math : Symbol(Math, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --))
11+
>random : Symbol(Math.random, Decl(lib.es5.d.ts, --, --))
12+
>a : Symbol(a, Decl(noUncheckedIndexAccessUnionProp1.ts, 2, 61))
13+
>b : Symbol(b, Decl(noUncheckedIndexAccessUnionProp1.ts, 2, 72))
14+
15+
const str = { a: "hello" };
16+
>str : Symbol(str, Decl(noUncheckedIndexAccessUnionProp1.ts, 3, 5))
17+
>a : Symbol(a, Decl(noUncheckedIndexAccessUnionProp1.ts, 3, 13))
18+
19+
const hmm = Math.random() < 0.5 ? nums.a : str.a;
20+
>hmm : Symbol(hmm, Decl(noUncheckedIndexAccessUnionProp1.ts, 5, 5))
21+
>Math.random : Symbol(Math.random, Decl(lib.es5.d.ts, --, --))
22+
>Math : Symbol(Math, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --))
23+
>random : Symbol(Math.random, Decl(lib.es5.d.ts, --, --))
24+
>nums.a : Symbol(__index, Decl(noUncheckedIndexAccessUnionProp1.ts, 2, 13))
25+
>nums : Symbol(nums, Decl(noUncheckedIndexAccessUnionProp1.ts, 2, 5))
26+
>a : Symbol(__index, Decl(noUncheckedIndexAccessUnionProp1.ts, 2, 13))
27+
>str.a : Symbol(a, Decl(noUncheckedIndexAccessUnionProp1.ts, 3, 13))
28+
>str : Symbol(str, Decl(noUncheckedIndexAccessUnionProp1.ts, 3, 5))
29+
>a : Symbol(a, Decl(noUncheckedIndexAccessUnionProp1.ts, 3, 13))
30+
31+
const wha = (Math.random() < 0.5 ? nums : str).a;
32+
>wha : Symbol(wha, Decl(noUncheckedIndexAccessUnionProp1.ts, 6, 5))
33+
>(Math.random() < 0.5 ? nums : str).a : Symbol(a, Decl(noUncheckedIndexAccessUnionProp1.ts, 3, 13))
34+
>Math.random : Symbol(Math.random, Decl(lib.es5.d.ts, --, --))
35+
>Math : Symbol(Math, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --))
36+
>random : Symbol(Math.random, Decl(lib.es5.d.ts, --, --))
37+
>nums : Symbol(nums, Decl(noUncheckedIndexAccessUnionProp1.ts, 2, 5))
38+
>str : Symbol(str, Decl(noUncheckedIndexAccessUnionProp1.ts, 3, 5))
39+
>a : Symbol(a, Decl(noUncheckedIndexAccessUnionProp1.ts, 3, 13))
40+
Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
//// [tests/cases/compiler/noUncheckedIndexAccessUnionProp1.ts] ////
2+
3+
=== noUncheckedIndexAccessUnionProp1.ts ===
4+
// https://github.com/microsoft/TypeScript/issues/61225
5+
6+
const nums: { [k: string]: number } = Math.random() < 0.5 ? { a: 1 } : { b: 2 };
7+
>nums : { [k: string]: number; }
8+
> : ^^^^^^^^^^^^^^^^^^^^^^^^
9+
>k : string
10+
> : ^^^^^^
11+
>Math.random() < 0.5 ? { a: 1 } : { b: 2 } : { a: number; } | { b: number; }
12+
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
13+
>Math.random() < 0.5 : boolean
14+
> : ^^^^^^^
15+
>Math.random() : number
16+
> : ^^^^^^
17+
>Math.random : () => number
18+
> : ^^^^^^
19+
>Math : Math
20+
> : ^^^^
21+
>random : () => number
22+
> : ^^^^^^
23+
>0.5 : 0.5
24+
> : ^^^
25+
>{ a: 1 } : { a: number; }
26+
> : ^^^^^^^^^^^^^^
27+
>a : number
28+
> : ^^^^^^
29+
>1 : 1
30+
> : ^
31+
>{ b: 2 } : { b: number; }
32+
> : ^^^^^^^^^^^^^^
33+
>b : number
34+
> : ^^^^^^
35+
>2 : 2
36+
> : ^
37+
38+
const str = { a: "hello" };
39+
>str : { a: string; }
40+
> : ^^^^^^^^^^^^^^
41+
>{ a: "hello" } : { a: string; }
42+
> : ^^^^^^^^^^^^^^
43+
>a : string
44+
> : ^^^^^^
45+
>"hello" : "hello"
46+
> : ^^^^^^^
47+
48+
const hmm = Math.random() < 0.5 ? nums.a : str.a;
49+
>hmm : string | number | undefined
50+
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^
51+
>Math.random() < 0.5 ? nums.a : str.a : string | number | undefined
52+
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^
53+
>Math.random() < 0.5 : boolean
54+
> : ^^^^^^^
55+
>Math.random() : number
56+
> : ^^^^^^
57+
>Math.random : () => number
58+
> : ^^^^^^
59+
>Math : Math
60+
> : ^^^^
61+
>random : () => number
62+
> : ^^^^^^
63+
>0.5 : 0.5
64+
> : ^^^
65+
>nums.a : number | undefined
66+
> : ^^^^^^^^^^^^^^^^^^
67+
>nums : { [k: string]: number; }
68+
> : ^^^^^^^^^^^^^^^^^^^^^^^^
69+
>a : number | undefined
70+
> : ^^^^^^^^^^^^^^^^^^
71+
>str.a : string
72+
> : ^^^^^^
73+
>str : { a: string; }
74+
> : ^^^^^^^^^^^^^^
75+
>a : string
76+
> : ^^^^^^
77+
78+
const wha = (Math.random() < 0.5 ? nums : str).a;
79+
>wha : string | number | undefined
80+
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^
81+
>(Math.random() < 0.5 ? nums : str).a : string | number | undefined
82+
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^
83+
>(Math.random() < 0.5 ? nums : str) : { [k: string]: number; } | { a: string; }
84+
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
85+
>Math.random() < 0.5 ? nums : str : { [k: string]: number; } | { a: string; }
86+
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
87+
>Math.random() < 0.5 : boolean
88+
> : ^^^^^^^
89+
>Math.random() : number
90+
> : ^^^^^^
91+
>Math.random : () => number
92+
> : ^^^^^^
93+
>Math : Math
94+
> : ^^^^
95+
>random : () => number
96+
> : ^^^^^^
97+
>0.5 : 0.5
98+
> : ^^^
99+
>nums : { [k: string]: number; }
100+
> : ^^^^^^^^^^^^^^^^^^^^^^^^
101+
>str : { a: string; }
102+
> : ^^^^^^^^^^^^^^
103+
>a : string | number | undefined
104+
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^
105+
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// @strict: true
2+
// @noUncheckedIndexedAccess: true
3+
// @noEmit: true
4+
5+
// https://github.com/microsoft/TypeScript/issues/61225
6+
7+
const nums: { [k: string]: number } = Math.random() < 0.5 ? { a: 1 } : { b: 2 };
8+
const str = { a: "hello" };
9+
10+
const hmm = Math.random() < 0.5 ? nums.a : str.a;
11+
const wha = (Math.random() < 0.5 ? nums : str).a;

0 commit comments

Comments
 (0)