Skip to content

Commit a40c90b

Browse files
committed
fix(declarations): preserve unique symbol keys in isolatedDeclarations
1 parent 479285d commit a40c90b

7 files changed

Lines changed: 122 additions & 3 deletions

src/compiler/transformers/declarations.ts

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -310,6 +310,20 @@ export function transformDeclarations(context: TransformationContext): Transform
310310
const { stripInternal, isolatedDeclarations } = options;
311311
return transformRoot;
312312

313+
function isUniqueSymbol(node: Expression): boolean {
314+
// A unique symbol type is represented as a TypeQueryNode (e.g. `typeof mySymbol`).
315+
// We can't get the `Type` object directly here, but we can check the kind of the node
316+
// the resolver creates.
317+
const typeNode = resolver.createTypeOfExpression(
318+
node,
319+
enclosingDeclaration,
320+
declarationEmitNodeBuilderFlags,
321+
declarationEmitInternalNodeBuilderFlags,
322+
symbolTracker
323+
);
324+
return !!typeNode && isTypeQueryNode(typeNode);
325+
}
326+
313327
function reportExpandoFunctionErrors(node: FunctionDeclaration | VariableDeclaration) {
314328
resolver.getPropertiesOfContainerFunction(node).forEach(p => {
315329
if (isExpandoPropertyDeclaration(p.valueDeclaration)) {
@@ -1010,7 +1024,8 @@ export function transformDeclarations(context: TransformationContext): Transform
10101024
// Classes and object literals usually elide properties with computed names that are not of a literal type
10111025
// In isolated declarations TSC needs to error on these as we don't know the type in a DTE.
10121026
if (!resolver.isDefinitelyReferenceToGlobalSymbolObject(input.name.expression)) {
1013-
if (isClassDeclaration(input.parent) || isObjectLiteralExpression(input.parent)) {
1027+
// Check if we're in a class/object literal context and the computed name is not a unique symbol
1028+
if ((isClassDeclaration(input.parent) || isObjectLiteralExpression(input.parent)) && !isUniqueSymbol(input.name.expression)) {
10141029
context.addDiagnostic(createDiagnosticForNode(input, Diagnostics.Computed_property_names_on_class_or_object_literals_cannot_be_inferred_with_isolatedDeclarations));
10151030
return;
10161031
}

tests/baselines/reference/isolatedDeclarationErrorsClasses.errors.txt

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,24 +9,33 @@ isolatedDeclarationErrorsClasses.ts(12,17): error TS7006: Parameter 'value' impl
99
isolatedDeclarationErrorsClasses.ts(12,17): error TS9009: At least one accessor must have an explicit type annotation with --isolatedDeclarations.
1010
isolatedDeclarationErrorsClasses.ts(36,5): error TS9038: Computed property names on class or object literals cannot be inferred with --isolatedDeclarations.
1111
isolatedDeclarationErrorsClasses.ts(36,6): error TS2304: Cannot find name 'missing'.
12+
isolatedDeclarationErrorsClasses.ts(36,6): error TS9013: Expression type can't be inferred with --isolatedDeclarations.
1213
isolatedDeclarationErrorsClasses.ts(38,5): error TS9038: Computed property names on class or object literals cannot be inferred with --isolatedDeclarations.
14+
isolatedDeclarationErrorsClasses.ts(38,6): error TS9013: Expression type can't be inferred with --isolatedDeclarations.
1315
isolatedDeclarationErrorsClasses.ts(40,5): error TS9038: Computed property names on class or object literals cannot be inferred with --isolatedDeclarations.
16+
isolatedDeclarationErrorsClasses.ts(40,6): error TS9013: Expression type can't be inferred with --isolatedDeclarations.
1417
isolatedDeclarationErrorsClasses.ts(42,5): error TS9008: Method must have an explicit return type annotation with --isolatedDeclarations.
1518
isolatedDeclarationErrorsClasses.ts(42,5): error TS9038: Computed property names on class or object literals cannot be inferred with --isolatedDeclarations.
19+
isolatedDeclarationErrorsClasses.ts(42,6): error TS9013: Expression type can't be inferred with --isolatedDeclarations.
1620
isolatedDeclarationErrorsClasses.ts(44,5): error TS9038: Computed property names on class or object literals cannot be inferred with --isolatedDeclarations.
21+
isolatedDeclarationErrorsClasses.ts(44,6): error TS9013: Expression type can't be inferred with --isolatedDeclarations.
1722
isolatedDeclarationErrorsClasses.ts(44,35): error TS7006: Parameter 'v' implicitly has an 'any' type.
1823
isolatedDeclarationErrorsClasses.ts(44,35): error TS9011: Parameter must have an explicit type annotation with --isolatedDeclarations.
1924
isolatedDeclarationErrorsClasses.ts(46,9): error TS9038: Computed property names on class or object literals cannot be inferred with --isolatedDeclarations.
25+
isolatedDeclarationErrorsClasses.ts(46,10): error TS9013: Expression type can't be inferred with --isolatedDeclarations.
2026
isolatedDeclarationErrorsClasses.ts(48,9): error TS7032: Property '[noParamAnnotationStringName]' implicitly has type 'any', because its set accessor lacks a parameter type annotation.
2127
isolatedDeclarationErrorsClasses.ts(48,9): error TS9038: Computed property names on class or object literals cannot be inferred with --isolatedDeclarations.
28+
isolatedDeclarationErrorsClasses.ts(48,10): error TS9013: Expression type can't be inferred with --isolatedDeclarations.
2229
isolatedDeclarationErrorsClasses.ts(48,39): error TS7006: Parameter 'value' implicitly has an 'any' type.
2330
isolatedDeclarationErrorsClasses.ts(50,5): error TS1166: A computed property name in a class property declaration must have a simple literal type or a 'unique symbol' type.
2431
isolatedDeclarationErrorsClasses.ts(50,5): error TS9038: Computed property names on class or object literals cannot be inferred with --isolatedDeclarations.
2532
isolatedDeclarationErrorsClasses.ts(56,5): error TS7010: '[noAnnotationLiteralName]', which lacks return-type annotation, implicitly has an 'any' return type.
2633
isolatedDeclarationErrorsClasses.ts(56,5): error TS9013: Expression type can't be inferred with --isolatedDeclarations.
34+
isolatedDeclarationErrorsClasses.ts(62,6): error TS9013: Expression type can't be inferred with --isolatedDeclarations.
35+
isolatedDeclarationErrorsClasses.ts(62,14): error TS9007: Function must have an explicit return type annotation with --isolatedDeclarations.
2736

2837

29-
==== isolatedDeclarationErrorsClasses.ts (26 errors) ====
38+
==== isolatedDeclarationErrorsClasses.ts (35 errors) ====
3039
export class Cls {
3140

3241
field = 1 + 1;
@@ -91,25 +100,37 @@ isolatedDeclarationErrorsClasses.ts(56,5): error TS9013: Expression type can't b
91100
!!! error TS9038: Computed property names on class or object literals cannot be inferred with --isolatedDeclarations.
92101
~~~~~~~
93102
!!! error TS2304: Cannot find name 'missing'.
103+
~~~~~~~
104+
!!! error TS9013: Expression type can't be inferred with --isolatedDeclarations.
105+
!!! related TS9029 isolatedDeclarationErrorsClasses.ts:36:5: Add a type annotation to the property [missing].
106+
!!! related TS9035 isolatedDeclarationErrorsClasses.ts:36:6: Add satisfies and a type assertion to this expression (satisfies T as T) to make the type explicit.
94107

95108
[noAnnotationLiteralName](): void { }
96109
~~~~~~~~~~~~~~~~~~~~~~~~~
97110
!!! error TS9038: Computed property names on class or object literals cannot be inferred with --isolatedDeclarations.
111+
~~~~~~~~~~~~~~~~~~~~~~~
112+
!!! error TS9013: Expression type can't be inferred with --isolatedDeclarations.
98113

99114
[noParamAnnotationLiteralName](v: string): void { }
100115
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
101116
!!! error TS9038: Computed property names on class or object literals cannot be inferred with --isolatedDeclarations.
117+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
118+
!!! error TS9013: Expression type can't be inferred with --isolatedDeclarations.
102119

103120
[noAnnotationStringName]() { }
104121
~~~~~~~~~~~~~~~~~~~~~~~~
105122
!!! error TS9008: Method must have an explicit return type annotation with --isolatedDeclarations.
106123
!!! related TS9034 isolatedDeclarationErrorsClasses.ts:42:5: Add a return type to the method
107124
~~~~~~~~~~~~~~~~~~~~~~~~
108125
!!! error TS9038: Computed property names on class or object literals cannot be inferred with --isolatedDeclarations.
126+
~~~~~~~~~~~~~~~~~~~~~~
127+
!!! error TS9013: Expression type can't be inferred with --isolatedDeclarations.
109128

110129
[noParamAnnotationStringName](v): void { }
111130
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
112131
!!! error TS9038: Computed property names on class or object literals cannot be inferred with --isolatedDeclarations.
132+
~~~~~~~~~~~~~~~~~~~~~~~~~~~
133+
!!! error TS9013: Expression type can't be inferred with --isolatedDeclarations.
113134
~
114135
!!! error TS7006: Parameter 'v' implicitly has an 'any' type.
115136
~
@@ -119,12 +140,16 @@ isolatedDeclarationErrorsClasses.ts(56,5): error TS9013: Expression type can't b
119140
get [noAnnotationStringName]() { return 0;}
120141
~~~~~~~~~~~~~~~~~~~~~~~~
121142
!!! error TS9038: Computed property names on class or object literals cannot be inferred with --isolatedDeclarations.
143+
~~~~~~~~~~~~~~~~~~~~~~
144+
!!! error TS9013: Expression type can't be inferred with --isolatedDeclarations.
122145

123146
set [noParamAnnotationStringName](value) { }
124147
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
125148
!!! error TS7032: Property '[noParamAnnotationStringName]' implicitly has type 'any', because its set accessor lacks a parameter type annotation.
126149
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
127150
!!! error TS9038: Computed property names on class or object literals cannot be inferred with --isolatedDeclarations.
151+
~~~~~~~~~~~~~~~~~~~~~~~~~~~
152+
!!! error TS9013: Expression type can't be inferred with --isolatedDeclarations.
128153
~~~~~
129154
!!! error TS7006: Parameter 'value' implicitly has an 'any' type.
130155

@@ -143,4 +168,18 @@ isolatedDeclarationErrorsClasses.ts(56,5): error TS9013: Expression type can't b
143168
!!! error TS7010: '[noAnnotationLiteralName]', which lacks return-type annotation, implicitly has an 'any' return type.
144169
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
145170
!!! error TS9013: Expression type can't be inferred with --isolatedDeclarations.
171+
}
172+
173+
export const prop: unique symbol = Symbol();
174+
175+
export class MyClass {
176+
[prop] = () => Math.random();
177+
~~~~
178+
!!! error TS9013: Expression type can't be inferred with --isolatedDeclarations.
179+
!!! related TS9029 isolatedDeclarationErrorsClasses.ts:62:5: Add a type annotation to the property [prop].
180+
!!! related TS9035 isolatedDeclarationErrorsClasses.ts:62:6: Add satisfies and a type assertion to this expression (satisfies T as T) to make the type explicit.
181+
~~~~~~~~~~~~~~~~~~~
182+
!!! error TS9007: Function must have an explicit return type annotation with --isolatedDeclarations.
183+
!!! related TS9029 isolatedDeclarationErrorsClasses.ts:62:5: Add a type annotation to the property [prop].
184+
!!! related TS9030 isolatedDeclarationErrorsClasses.ts:62:14: Add a return type to the function expression.
146185
}

tests/baselines/reference/isolatedDeclarationErrorsClasses.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,12 @@ export class C {
5757
export interface I {
5858
[noAnnotationStringName]: 10;
5959
[noAnnotationLiteralName]();
60+
}
61+
62+
export const prop: unique symbol = Symbol();
63+
64+
export class MyClass {
65+
[prop] = () => Math.random();
6066
}
6167

6268
//// [isolatedDeclarationErrorsClasses.js]
@@ -92,3 +98,7 @@ export class C {
9298
set [noParamAnnotationStringName](value) { }
9399
[("A" + "B")] = 1;
94100
}
101+
export const prop = Symbol();
102+
export class MyClass {
103+
[prop] = () => Math.random();
104+
}

tests/baselines/reference/isolatedDeclarationErrorsClasses.symbols

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,3 +119,18 @@ export interface I {
119119
>[noAnnotationLiteralName] : Symbol(I[noAnnotationLiteralName], Decl(isolatedDeclarationErrorsClasses.ts, 54, 33))
120120
>noAnnotationLiteralName : Symbol(noAnnotationLiteralName, Decl(isolatedDeclarationErrorsClasses.ts, 29, 5))
121121
}
122+
123+
export const prop: unique symbol = Symbol();
124+
>prop : Symbol(prop, Decl(isolatedDeclarationErrorsClasses.ts, 58, 12))
125+
>Symbol : Symbol(Symbol, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2019.symbol.d.ts, --, --))
126+
127+
export class MyClass {
128+
>MyClass : Symbol(MyClass, Decl(isolatedDeclarationErrorsClasses.ts, 58, 44))
129+
130+
[prop] = () => Math.random();
131+
>[prop] : Symbol(MyClass[prop], Decl(isolatedDeclarationErrorsClasses.ts, 60, 22))
132+
>prop : Symbol(prop, Decl(isolatedDeclarationErrorsClasses.ts, 58, 12))
133+
>Math.random : Symbol(Math.random, Decl(lib.es5.d.ts, --, --))
134+
>Math : Symbol(Math, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.esnext.float16.d.ts, --, --))
135+
>random : Symbol(Math.random, Decl(lib.es5.d.ts, --, --))
136+
}

tests/baselines/reference/isolatedDeclarationErrorsClasses.types

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -218,3 +218,32 @@ export interface I {
218218
>noAnnotationLiteralName : "noAnnotationLiteralName"
219219
> : ^^^^^^^^^^^^^^^^^^^^^^^^^
220220
}
221+
222+
export const prop: unique symbol = Symbol();
223+
>prop : unique symbol
224+
> : ^^^^^^^^^^^^^
225+
>Symbol() : unique symbol
226+
> : ^^^^^^^^^^^^^
227+
>Symbol : SymbolConstructor
228+
> : ^^^^^^^^^^^^^^^^^
229+
230+
export class MyClass {
231+
>MyClass : MyClass
232+
> : ^^^^^^^
233+
234+
[prop] = () => Math.random();
235+
>[prop] : () => number
236+
> : ^^^^^^^^^^^^
237+
>prop : unique symbol
238+
> : ^^^^^^^^^^^^^
239+
>() => Math.random() : () => number
240+
> : ^^^^^^^^^^^^
241+
>Math.random() : number
242+
> : ^^^^^^
243+
>Math.random : () => number
244+
> : ^^^^^^
245+
>Math : Math
246+
> : ^^^^
247+
>random : () => number
248+
> : ^^^^^^
249+
}

tests/baselines/reference/isolatedDeclarationLazySymbols.errors.txt

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,12 @@ isolatedDeclarationLazySymbols.ts(1,17): error TS9007: Function must have an exp
22
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.
33
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.
5+
isolatedDeclarationLazySymbols.ts(16,6): error TS9013: Expression type can't be inferred with --isolatedDeclarations.
56
isolatedDeclarationLazySymbols.ts(21,5): error TS9038: Computed property names on class or object literals cannot be inferred with --isolatedDeclarations.
67
isolatedDeclarationLazySymbols.ts(22,5): error TS9038: Computed property names on class or object literals cannot be inferred with --isolatedDeclarations.
78

89

9-
==== isolatedDeclarationLazySymbols.ts (6 errors) ====
10+
==== isolatedDeclarationLazySymbols.ts (7 errors) ====
1011
export function foo() {
1112
~~~
1213
!!! error TS9007: Function must have an explicit return type annotation with --isolatedDeclarations.
@@ -32,6 +33,10 @@ isolatedDeclarationLazySymbols.ts(22,5): error TS9038: Computed property names o
3233
!!! error TS1166: A computed property name in a class property declaration must have a simple literal type or a 'unique symbol' type.
3334
~~~~~~~~~~~~~~~~~
3435
!!! error TS9038: Computed property names on class or object literals cannot be inferred with --isolatedDeclarations.
36+
~~~~~~~~~~~~~~~
37+
!!! error TS9013: Expression type can't be inferred with --isolatedDeclarations.
38+
!!! related TS9029 isolatedDeclarationLazySymbols.ts:16:5: Add a type annotation to the property [o["prop.inner"]].
39+
!!! related TS9035 isolatedDeclarationLazySymbols.ts:16:6: Add satisfies and a type assertion to this expression (satisfies T as T) to make the type explicit.
3540
[o.prop.inner] = "B"
3641
}
3742

tests/cases/compiler/isolatedDeclarationErrorsClasses.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,4 +60,10 @@ export class C {
6060
export interface I {
6161
[noAnnotationStringName]: 10;
6262
[noAnnotationLiteralName]();
63+
}
64+
65+
export const prop: unique symbol = Symbol();
66+
67+
export class MyClass {
68+
[prop] = () => Math.random();
6369
}

0 commit comments

Comments
 (0)