Skip to content

Commit 91424d8

Browse files
committed
fix(checker): Allow element access expressions in computed property names if argument is literal
1 parent 69bcbc4 commit 91424d8

File tree

6 files changed

+353
-102
lines changed

6 files changed

+353
-102
lines changed

src/compiler/utilities.ts

Lines changed: 105 additions & 97 deletions
Large diffs are not rendered by default.
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
//// [tests/cases/compiler/enumKeysInTypeLiteral.ts] ////
2+
3+
//// [enumKeysInTypeLiteral.ts]
4+
enum Type {
5+
Foo = 'foo',
6+
'3x14' = '3x14'
7+
}
8+
9+
type TypeMap = {
10+
[Type.Foo]: 1;
11+
[Type['3x14']]: 2;
12+
}
13+
14+
const t: TypeMap = {
15+
'foo': 1,
16+
'3x14': 2
17+
};
18+
19+
enum Numeric {
20+
Negative = -1,
21+
Zero = 0
22+
}
23+
24+
type NumericMap = {
25+
// Valid: Accessing enum member via string literal for the name
26+
[Numeric['Negative']]: number;
27+
[Numeric['Zero']]: number;
28+
// Valid: Parenthesized access
29+
[Numeric[('Negative')]]: number;
30+
}
31+
32+
33+
34+
//// [enumKeysInTypeLiteral.js]
35+
var Type;
36+
(function (Type) {
37+
Type["Foo"] = "foo";
38+
Type["3x14"] = "3x14";
39+
})(Type || (Type = {}));
40+
var t = {
41+
'foo': 1,
42+
'3x14': 2
43+
};
44+
var Numeric;
45+
(function (Numeric) {
46+
Numeric[Numeric["Negative"] = -1] = "Negative";
47+
Numeric[Numeric["Zero"] = 0] = "Zero";
48+
})(Numeric || (Numeric = {}));
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
//// [tests/cases/compiler/enumKeysInTypeLiteral.ts] ////
2+
3+
=== enumKeysInTypeLiteral.ts ===
4+
enum Type {
5+
>Type : Symbol(Type, Decl(enumKeysInTypeLiteral.ts, 0, 0))
6+
7+
Foo = 'foo',
8+
>Foo : Symbol(Type.Foo, Decl(enumKeysInTypeLiteral.ts, 0, 11))
9+
10+
'3x14' = '3x14'
11+
>'3x14' : Symbol(Type['3x14'], Decl(enumKeysInTypeLiteral.ts, 1, 14))
12+
}
13+
14+
type TypeMap = {
15+
>TypeMap : Symbol(TypeMap, Decl(enumKeysInTypeLiteral.ts, 3, 1))
16+
17+
[Type.Foo]: 1;
18+
>[Type.Foo] : Symbol([Type.Foo], Decl(enumKeysInTypeLiteral.ts, 5, 16))
19+
>Type.Foo : Symbol(Type.Foo, Decl(enumKeysInTypeLiteral.ts, 0, 11))
20+
>Type : Symbol(Type, Decl(enumKeysInTypeLiteral.ts, 0, 0))
21+
>Foo : Symbol(Type.Foo, Decl(enumKeysInTypeLiteral.ts, 0, 11))
22+
23+
[Type['3x14']]: 2;
24+
>[Type['3x14']] : Symbol([Type['3x14']], Decl(enumKeysInTypeLiteral.ts, 6, 16))
25+
>Type : Symbol(Type, Decl(enumKeysInTypeLiteral.ts, 0, 0))
26+
>'3x14' : Symbol(Type['3x14'], Decl(enumKeysInTypeLiteral.ts, 1, 14))
27+
}
28+
29+
const t: TypeMap = {
30+
>t : Symbol(t, Decl(enumKeysInTypeLiteral.ts, 10, 5))
31+
>TypeMap : Symbol(TypeMap, Decl(enumKeysInTypeLiteral.ts, 3, 1))
32+
33+
'foo': 1,
34+
>'foo' : Symbol('foo', Decl(enumKeysInTypeLiteral.ts, 10, 20))
35+
36+
'3x14': 2
37+
>'3x14' : Symbol('3x14', Decl(enumKeysInTypeLiteral.ts, 11, 13))
38+
39+
};
40+
41+
enum Numeric {
42+
>Numeric : Symbol(Numeric, Decl(enumKeysInTypeLiteral.ts, 13, 2))
43+
44+
Negative = -1,
45+
>Negative : Symbol(Numeric.Negative, Decl(enumKeysInTypeLiteral.ts, 15, 14))
46+
47+
Zero = 0
48+
>Zero : Symbol(Numeric.Zero, Decl(enumKeysInTypeLiteral.ts, 16, 18))
49+
}
50+
51+
type NumericMap = {
52+
>NumericMap : Symbol(NumericMap, Decl(enumKeysInTypeLiteral.ts, 18, 1))
53+
54+
// Valid: Accessing enum member via string literal for the name
55+
[Numeric['Negative']]: number;
56+
>[Numeric['Negative']] : Symbol([Numeric['Negative']], Decl(enumKeysInTypeLiteral.ts, 20, 19), Decl(enumKeysInTypeLiteral.ts, 23, 30))
57+
>Numeric : Symbol(Numeric, Decl(enumKeysInTypeLiteral.ts, 13, 2))
58+
>'Negative' : Symbol(Numeric.Negative, Decl(enumKeysInTypeLiteral.ts, 15, 14))
59+
60+
[Numeric['Zero']]: number;
61+
>[Numeric['Zero']] : Symbol([Numeric['Zero']], Decl(enumKeysInTypeLiteral.ts, 22, 34))
62+
>Numeric : Symbol(Numeric, Decl(enumKeysInTypeLiteral.ts, 13, 2))
63+
>'Zero' : Symbol(Numeric.Zero, Decl(enumKeysInTypeLiteral.ts, 16, 18))
64+
65+
// Valid: Parenthesized access
66+
[Numeric[('Negative')]]: number;
67+
>[Numeric[('Negative')]] : Symbol([Numeric['Negative']], Decl(enumKeysInTypeLiteral.ts, 20, 19), Decl(enumKeysInTypeLiteral.ts, 23, 30))
68+
>Numeric : Symbol(Numeric, Decl(enumKeysInTypeLiteral.ts, 13, 2))
69+
}
70+
71+
Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
//// [tests/cases/compiler/enumKeysInTypeLiteral.ts] ////
2+
3+
=== enumKeysInTypeLiteral.ts ===
4+
enum Type {
5+
>Type : Type
6+
> : ^^^^
7+
8+
Foo = 'foo',
9+
>Foo : Type.Foo
10+
> : ^^^^^^^^
11+
>'foo' : "foo"
12+
> : ^^^^^
13+
14+
'3x14' = '3x14'
15+
>'3x14' : (typeof Type)["3x14"]
16+
> : ^^^^^^^^^^^^^^^^^^^^^
17+
>'3x14' : "3x14"
18+
> : ^^^^^^
19+
}
20+
21+
type TypeMap = {
22+
>TypeMap : TypeMap
23+
> : ^^^^^^^
24+
25+
[Type.Foo]: 1;
26+
>[Type.Foo] : 1
27+
> : ^
28+
>Type.Foo : Type.Foo
29+
> : ^^^^^^^^
30+
>Type : typeof Type
31+
> : ^^^^^^^^^^^
32+
>Foo : Type.Foo
33+
> : ^^^^^^^^
34+
35+
[Type['3x14']]: 2;
36+
>[Type['3x14']] : 2
37+
> : ^
38+
>Type['3x14'] : (typeof Type)["3x14"]
39+
> : ^^^^^^^^^^^^^^^^^^^^^
40+
>Type : typeof Type
41+
> : ^^^^^^^^^^^
42+
>'3x14' : "3x14"
43+
> : ^^^^^^
44+
}
45+
46+
const t: TypeMap = {
47+
>t : TypeMap
48+
> : ^^^^^^^
49+
>{ 'foo': 1, '3x14': 2} : { foo: 1; '3x14': 2; }
50+
> : ^^^^^^^^^^^^^^^^^^^^^^
51+
52+
'foo': 1,
53+
>'foo' : 1
54+
> : ^
55+
>1 : 1
56+
> : ^
57+
58+
'3x14': 2
59+
>'3x14' : 2
60+
> : ^
61+
>2 : 2
62+
> : ^
63+
64+
};
65+
66+
enum Numeric {
67+
>Numeric : Numeric
68+
> : ^^^^^^^
69+
70+
Negative = -1,
71+
>Negative : Numeric.Negative
72+
> : ^^^^^^^^^^^^^^^^
73+
>-1 : -1
74+
> : ^^
75+
>1 : 1
76+
> : ^
77+
78+
Zero = 0
79+
>Zero : Numeric.Zero
80+
> : ^^^^^^^^^^^^
81+
>0 : 0
82+
> : ^
83+
}
84+
85+
type NumericMap = {
86+
>NumericMap : NumericMap
87+
> : ^^^^^^^^^^
88+
89+
// Valid: Accessing enum member via string literal for the name
90+
[Numeric['Negative']]: number;
91+
>[Numeric['Negative']] : number
92+
> : ^^^^^^
93+
>Numeric['Negative'] : Numeric.Negative
94+
> : ^^^^^^^^^^^^^^^^
95+
>Numeric : typeof Numeric
96+
> : ^^^^^^^^^^^^^^
97+
>'Negative' : "Negative"
98+
> : ^^^^^^^^^^
99+
100+
[Numeric['Zero']]: number;
101+
>[Numeric['Zero']] : number
102+
> : ^^^^^^
103+
>Numeric['Zero'] : Numeric.Zero
104+
> : ^^^^^^^^^^^^
105+
>Numeric : typeof Numeric
106+
> : ^^^^^^^^^^^^^^
107+
>'Zero' : "Zero"
108+
> : ^^^^^^
109+
110+
// Valid: Parenthesized access
111+
[Numeric[('Negative')]]: number;
112+
>[Numeric[('Negative')]] : number
113+
> : ^^^^^^
114+
>Numeric[('Negative')] : Numeric.Negative
115+
> : ^^^^^^^^^^^^^^^^
116+
>Numeric : typeof Numeric
117+
> : ^^^^^^^^^^^^^^
118+
>('Negative') : "Negative"
119+
> : ^^^^^^^^^^
120+
>'Negative' : "Negative"
121+
> : ^^^^^^^^^^
122+
}
123+
124+

tests/baselines/reference/isolatedDeclarationLazySymbols.errors.txt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
isolatedDeclarationLazySymbols.ts(1,17): error TS9007: Function must have an explicit return type annotation with --isolatedDeclarations.
2+
isolatedDeclarationLazySymbols.ts(12,1): error TS9023: Assigning properties to functions without declaring them is not supported with --isolatedDeclarations. Add an explicit declaration for the properties assigned to this function.
23
isolatedDeclarationLazySymbols.ts(13,1): error TS9023: Assigning properties to functions without declaring them is not supported with --isolatedDeclarations. Add an explicit declaration for the properties assigned to this function.
3-
isolatedDeclarationLazySymbols.ts(16,5): error TS1166: A computed property name in a class property declaration must have a simple literal type or a 'unique symbol' type.
44
isolatedDeclarationLazySymbols.ts(16,5): error TS9038: Computed property names on class or object literals cannot be inferred with --isolatedDeclarations.
55
isolatedDeclarationLazySymbols.ts(21,5): error TS9038: Computed property names on class or object literals cannot be inferred with --isolatedDeclarations.
66
isolatedDeclarationLazySymbols.ts(22,5): error TS9038: Computed property names on class or object literals cannot be inferred with --isolatedDeclarations.
@@ -22,15 +22,15 @@ isolatedDeclarationLazySymbols.ts(22,5): error TS9038: Computed property names o
2222
} as const
2323

2424
foo[o["prop.inner"]] ="A";
25+
~~~~~~~~~~~~~~~~~~~~
26+
!!! error TS9023: Assigning properties to functions without declaring them is not supported with --isolatedDeclarations. Add an explicit declaration for the properties assigned to this function.
2527
foo[o.prop.inner] = "B";
2628
~~~~~~~~~~~~~~~~~
2729
!!! error TS9023: Assigning properties to functions without declaring them is not supported with --isolatedDeclarations. Add an explicit declaration for the properties assigned to this function.
2830

2931
export class Foo {
3032
[o["prop.inner"]] ="A"
3133
~~~~~~~~~~~~~~~~~
32-
!!! error TS1166: A computed property name in a class property declaration must have a simple literal type or a 'unique symbol' type.
33-
~~~~~~~~~~~~~~~~~
3434
!!! error TS9038: Computed property names on class or object literals cannot be inferred with --isolatedDeclarations.
3535
[o.prop.inner] = "B"
3636
}

tests/baselines/reference/isolatedDeclarationLazySymbols.types

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,8 @@ const o = {
4040
foo[o["prop.inner"]] ="A";
4141
>foo[o["prop.inner"]] ="A" : "A"
4242
> : ^^^
43-
>foo[o["prop.inner"]] : any
44-
> : ^^^
43+
>foo[o["prop.inner"]] : string
44+
> : ^^^^^^
4545
>foo : typeof foo
4646
> : ^^^^^^^^^^
4747
>o["prop.inner"] : "a"

0 commit comments

Comments
 (0)