Skip to content

Commit 552b07e

Browse files
TypeScript BotAndarist
TypeScript Bot
andauthored
🤖 Pick PR #58786 (Fixed declaration emit crash relate...) into release-5.5 (#58853)
Co-authored-by: Mateusz BurzyÅ„ski <[email protected]>
1 parent 39c9eeb commit 552b07e

25 files changed

+663
-2
lines changed

Diff for: ‎src/compiler/checker.ts

+17-2
Original file line numberDiff line numberDiff line change
@@ -8840,8 +8840,23 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
88408840
else {
88418841
const type = getWidenedType(getRegularTypeOfExpression(node.expression));
88428842
const computedPropertyNameType = typeToTypeNodeHelper(type, context);
8843-
Debug.assertNode(computedPropertyNameType, isLiteralTypeNode);
8844-
const literal = computedPropertyNameType.literal;
8843+
let literal;
8844+
if (isLiteralTypeNode(computedPropertyNameType)) {
8845+
literal = computedPropertyNameType.literal;
8846+
}
8847+
else {
8848+
const evaluated = evaluateEntityNameExpression(node.expression);
8849+
const literalNode = typeof evaluated.value === "string" ? factory.createStringLiteral(evaluated.value, /*isSingleQuote*/ undefined) :
8850+
typeof evaluated.value === "number" ? factory.createNumericLiteral(evaluated.value, /*numericLiteralFlags*/ 0) :
8851+
undefined;
8852+
if (!literalNode) {
8853+
if (isImportTypeNode(computedPropertyNameType)) {
8854+
trackComputedName(node.expression, context.enclosingDeclaration, context);
8855+
}
8856+
return node;
8857+
}
8858+
literal = literalNode;
8859+
}
88458860
if (literal.kind === SyntaxKind.StringLiteral && isIdentifierText(literal.text, getEmitScriptTarget(compilerOptions))) {
88468861
return factory.createIdentifier(literal.text);
88478862
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
//// [tests/cases/compiler/declarationEmitComputedPropertyNameEnum1.ts] ////
2+
3+
//// [type.ts]
4+
export enum Enum {
5+
A = "a",
6+
B = "b"
7+
}
8+
9+
export type Type = { x?: { [Enum.A]: 0 } };
10+
11+
//// [index.ts]
12+
import { type Type } from "./type";
13+
14+
export const foo = { ...({} as Type) };
15+
16+
17+
18+
19+
//// [type.d.ts]
20+
export declare enum Enum {
21+
A = "a",
22+
B = "b"
23+
}
24+
export type Type = {
25+
x?: {
26+
[Enum.A]: 0;
27+
};
28+
};
29+
//// [index.d.ts]
30+
export declare const foo: {
31+
x?: {
32+
a: 0;
33+
};
34+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
//// [tests/cases/compiler/declarationEmitComputedPropertyNameEnum1.ts] ////
2+
3+
=== type.ts ===
4+
export enum Enum {
5+
>Enum : Symbol(Enum, Decl(type.ts, 0, 0))
6+
7+
A = "a",
8+
>A : Symbol(Enum.A, Decl(type.ts, 0, 18))
9+
10+
B = "b"
11+
>B : Symbol(Enum.B, Decl(type.ts, 1, 10))
12+
}
13+
14+
export type Type = { x?: { [Enum.A]: 0 } };
15+
>Type : Symbol(Type, Decl(type.ts, 3, 1))
16+
>x : Symbol(x, Decl(type.ts, 5, 20))
17+
>[Enum.A] : Symbol([Enum.A], Decl(type.ts, 5, 26))
18+
>Enum.A : Symbol(Enum.A, Decl(type.ts, 0, 18))
19+
>Enum : Symbol(Enum, Decl(type.ts, 0, 0))
20+
>A : Symbol(Enum.A, Decl(type.ts, 0, 18))
21+
22+
=== index.ts ===
23+
import { type Type } from "./type";
24+
>Type : Symbol(Type, Decl(index.ts, 0, 8))
25+
26+
export const foo = { ...({} as Type) };
27+
>foo : Symbol(foo, Decl(index.ts, 2, 12))
28+
>Type : Symbol(Type, Decl(index.ts, 0, 8))
29+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
//// [tests/cases/compiler/declarationEmitComputedPropertyNameEnum1.ts] ////
2+
3+
=== type.ts ===
4+
export enum Enum {
5+
>Enum : Enum
6+
> : ^^^^
7+
8+
A = "a",
9+
>A : Enum.A
10+
> : ^^^^^^
11+
>"a" : "a"
12+
> : ^^^
13+
14+
B = "b"
15+
>B : Enum.B
16+
> : ^^^^^^
17+
>"b" : "b"
18+
> : ^^^
19+
}
20+
21+
export type Type = { x?: { [Enum.A]: 0 } };
22+
>Type : Type
23+
> : ^^^^
24+
>x : { a: 0; } | undefined
25+
> : ^^^^^ ^^^^^^^^^^^^^^^
26+
>[Enum.A] : 0
27+
> : ^
28+
>Enum.A : Enum.A
29+
> : ^^^^^^
30+
>Enum : typeof Enum
31+
> : ^^^^^^^^^^^
32+
>A : Enum.A
33+
> : ^^^^^^
34+
35+
=== index.ts ===
36+
import { type Type } from "./type";
37+
>Type : any
38+
> : ^^^
39+
40+
export const foo = { ...({} as Type) };
41+
>foo : { x?: { a: 0; }; }
42+
> : ^^^^^^ ^^^
43+
>{ ...({} as Type) } : { x?: { a: 0; }; }
44+
> : ^^^^^^ ^^^
45+
>({} as Type) : Type
46+
> : ^^^^
47+
>{} as Type : Type
48+
> : ^^^^
49+
>{} : {}
50+
> : ^^
51+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
type.ts(1,28): error TS1170: A computed property name in a type literal must refer to an expression whose type is a literal type or a 'unique symbol' type.
2+
type.ts(1,29): error TS2304: Cannot find name 'Enum'.
3+
4+
5+
==== type.ts (2 errors) ====
6+
export type Type = { x?: { [Enum.A]: 0 } };
7+
~~~~~~~~
8+
!!! error TS1170: A computed property name in a type literal must refer to an expression whose type is a literal type or a 'unique symbol' type.
9+
~~~~
10+
!!! error TS2304: Cannot find name 'Enum'.
11+
12+
==== index.ts (0 errors) ====
13+
import { type Type } from "./type";
14+
15+
export const foo = { ...({} as Type) };
16+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
//// [tests/cases/compiler/declarationEmitComputedPropertyNameEnum2.ts] ////
2+
3+
//// [type.ts]
4+
export type Type = { x?: { [Enum.A]: 0 } };
5+
6+
//// [index.ts]
7+
import { type Type } from "./type";
8+
9+
export const foo = { ...({} as Type) };
10+
11+
12+
13+
14+
//// [type.d.ts]
15+
export type Type = {
16+
x?: {};
17+
};
18+
//// [index.d.ts]
19+
export declare const foo: {
20+
x?: {
21+
[Enum.A]: 0;
22+
};
23+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
//// [tests/cases/compiler/declarationEmitComputedPropertyNameEnum2.ts] ////
2+
3+
=== type.ts ===
4+
export type Type = { x?: { [Enum.A]: 0 } };
5+
>Type : Symbol(Type, Decl(type.ts, 0, 0))
6+
>x : Symbol(x, Decl(type.ts, 0, 20))
7+
>[Enum.A] : Symbol([Enum.A], Decl(type.ts, 0, 26))
8+
9+
=== index.ts ===
10+
import { type Type } from "./type";
11+
>Type : Symbol(Type, Decl(index.ts, 0, 8))
12+
13+
export const foo = { ...({} as Type) };
14+
>foo : Symbol(foo, Decl(index.ts, 2, 12))
15+
>Type : Symbol(Type, Decl(index.ts, 0, 8))
16+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
//// [tests/cases/compiler/declarationEmitComputedPropertyNameEnum2.ts] ////
2+
3+
=== type.ts ===
4+
export type Type = { x?: { [Enum.A]: 0 } };
5+
>Type : Type
6+
> : ^^^^
7+
>x : {} | undefined
8+
> : ^^^^^^^^^^^^^^
9+
>[Enum.A] : 0
10+
> : ^
11+
>Enum.A : any
12+
> : ^^^
13+
>Enum : any
14+
> : ^^^
15+
>A : any
16+
> : ^^^
17+
18+
=== index.ts ===
19+
import { type Type } from "./type";
20+
>Type : any
21+
> : ^^^
22+
23+
export const foo = { ...({} as Type) };
24+
>foo : { x?: { [Enum.A]: 0; }; }
25+
> : ^^^^^^ ^^^
26+
>{ ...({} as Type) } : { x?: { [Enum.A]: 0; }; }
27+
> : ^^^^^^ ^^^
28+
>({} as Type) : Type
29+
> : ^^^^
30+
>{} as Type : Type
31+
> : ^^^^
32+
>{} : {}
33+
> : ^^
34+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
type.ts(7,28): error TS1170: A computed property name in a type literal must refer to an expression whose type is a literal type or a 'unique symbol' type.
2+
type.ts(7,28): error TS2464: A computed property name must be of type 'string', 'number', 'symbol', or 'any'.
3+
4+
5+
==== type.ts (2 errors) ====
6+
export namespace Foo {
7+
export enum Enum {
8+
A = "a",
9+
B = "b",
10+
}
11+
}
12+
export type Type = { x?: { [Foo.Enum]: 0 } };
13+
~~~~~~~~~~
14+
!!! error TS1170: A computed property name in a type literal must refer to an expression whose type is a literal type or a 'unique symbol' type.
15+
~~~~~~~~~~
16+
!!! error TS2464: A computed property name must be of type 'string', 'number', 'symbol', or 'any'.
17+
18+
==== index.ts (0 errors) ====
19+
import { type Type } from "./type";
20+
21+
export const foo = { ...({} as Type) };
22+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
//// [tests/cases/compiler/declarationEmitComputedPropertyNameEnum3.ts] ////
2+
3+
//// [type.ts]
4+
export namespace Foo {
5+
export enum Enum {
6+
A = "a",
7+
B = "b",
8+
}
9+
}
10+
export type Type = { x?: { [Foo.Enum]: 0 } };
11+
12+
//// [index.ts]
13+
import { type Type } from "./type";
14+
15+
export const foo = { ...({} as Type) };
16+
17+
18+
19+
20+
//// [type.d.ts]
21+
export declare namespace Foo {
22+
enum Enum {
23+
A = "a",
24+
B = "b"
25+
}
26+
}
27+
export type Type = {
28+
x?: {};
29+
};
30+
//// [index.d.ts]
31+
export declare const foo: {
32+
x?: {};
33+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
//// [tests/cases/compiler/declarationEmitComputedPropertyNameEnum3.ts] ////
2+
3+
=== type.ts ===
4+
export namespace Foo {
5+
>Foo : Symbol(Foo, Decl(type.ts, 0, 0))
6+
7+
export enum Enum {
8+
>Enum : Symbol(Enum, Decl(type.ts, 0, 22))
9+
10+
A = "a",
11+
>A : Symbol(Enum.A, Decl(type.ts, 1, 20))
12+
13+
B = "b",
14+
>B : Symbol(Enum.B, Decl(type.ts, 2, 12))
15+
}
16+
}
17+
export type Type = { x?: { [Foo.Enum]: 0 } };
18+
>Type : Symbol(Type, Decl(type.ts, 5, 1))
19+
>x : Symbol(x, Decl(type.ts, 6, 20))
20+
>[Foo.Enum] : Symbol([Foo.Enum], Decl(type.ts, 6, 26))
21+
>Foo.Enum : Symbol(Foo.Enum, Decl(type.ts, 0, 22))
22+
>Foo : Symbol(Foo, Decl(type.ts, 0, 0))
23+
>Enum : Symbol(Foo.Enum, Decl(type.ts, 0, 22))
24+
25+
=== index.ts ===
26+
import { type Type } from "./type";
27+
>Type : Symbol(Type, Decl(index.ts, 0, 8))
28+
29+
export const foo = { ...({} as Type) };
30+
>foo : Symbol(foo, Decl(index.ts, 2, 12))
31+
>Type : Symbol(Type, Decl(index.ts, 0, 8))
32+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
//// [tests/cases/compiler/declarationEmitComputedPropertyNameEnum3.ts] ////
2+
3+
=== type.ts ===
4+
export namespace Foo {
5+
>Foo : typeof Foo
6+
> : ^^^^^^^^^^
7+
8+
export enum Enum {
9+
>Enum : Enum
10+
> : ^^^^
11+
12+
A = "a",
13+
>A : Enum.A
14+
> : ^^^^^^
15+
>"a" : "a"
16+
> : ^^^
17+
18+
B = "b",
19+
>B : Enum.B
20+
> : ^^^^^^
21+
>"b" : "b"
22+
> : ^^^
23+
}
24+
}
25+
export type Type = { x?: { [Foo.Enum]: 0 } };
26+
>Type : Type
27+
> : ^^^^
28+
>x : {} | undefined
29+
> : ^^^^^^^^^^^^^^
30+
>[Foo.Enum] : 0
31+
> : ^
32+
>Foo.Enum : typeof Foo.Enum
33+
> : ^^^^^^^^^^^^^^^
34+
>Foo : typeof Foo
35+
> : ^^^^^^^^^^
36+
>Enum : typeof Foo.Enum
37+
> : ^^^^^^^^^^^^^^^
38+
39+
=== index.ts ===
40+
import { type Type } from "./type";
41+
>Type : any
42+
> : ^^^
43+
44+
export const foo = { ...({} as Type) };
45+
>foo : { x?: {}; }
46+
> : ^^^^^^ ^^^
47+
>{ ...({} as Type) } : { x?: {}; }
48+
> : ^^^^^^ ^^^
49+
>({} as Type) : Type
50+
> : ^^^^
51+
>{} as Type : Type
52+
> : ^^^^
53+
>{} : {}
54+
> : ^^
55+

0 commit comments

Comments
 (0)