🤖 Pick PR #58786 (Fixed declaration emit crash relate...) into release-5.5 (#58853)

Co-authored-by: Mateusz Burzyński <mateuszburzynski@gmail.com>
This commit is contained in:
TypeScript Bot 2024-06-14 18:21:52 -07:00 committed by GitHub
parent 39c9eebf17
commit 552b07e795
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
25 changed files with 663 additions and 2 deletions

View File

@ -8840,8 +8840,23 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
else {
const type = getWidenedType(getRegularTypeOfExpression(node.expression));
const computedPropertyNameType = typeToTypeNodeHelper(type, context);
Debug.assertNode(computedPropertyNameType, isLiteralTypeNode);
const literal = computedPropertyNameType.literal;
let literal;
if (isLiteralTypeNode(computedPropertyNameType)) {
literal = computedPropertyNameType.literal;
}
else {
const evaluated = evaluateEntityNameExpression(node.expression);
const literalNode = typeof evaluated.value === "string" ? factory.createStringLiteral(evaluated.value, /*isSingleQuote*/ undefined) :
typeof evaluated.value === "number" ? factory.createNumericLiteral(evaluated.value, /*numericLiteralFlags*/ 0) :
undefined;
if (!literalNode) {
if (isImportTypeNode(computedPropertyNameType)) {
trackComputedName(node.expression, context.enclosingDeclaration, context);
}
return node;
}
literal = literalNode;
}
if (literal.kind === SyntaxKind.StringLiteral && isIdentifierText(literal.text, getEmitScriptTarget(compilerOptions))) {
return factory.createIdentifier(literal.text);
}

View File

@ -0,0 +1,34 @@
//// [tests/cases/compiler/declarationEmitComputedPropertyNameEnum1.ts] ////
//// [type.ts]
export enum Enum {
A = "a",
B = "b"
}
export type Type = { x?: { [Enum.A]: 0 } };
//// [index.ts]
import { type Type } from "./type";
export const foo = { ...({} as Type) };
//// [type.d.ts]
export declare enum Enum {
A = "a",
B = "b"
}
export type Type = {
x?: {
[Enum.A]: 0;
};
};
//// [index.d.ts]
export declare const foo: {
x?: {
a: 0;
};
};

View File

@ -0,0 +1,29 @@
//// [tests/cases/compiler/declarationEmitComputedPropertyNameEnum1.ts] ////
=== type.ts ===
export enum Enum {
>Enum : Symbol(Enum, Decl(type.ts, 0, 0))
A = "a",
>A : Symbol(Enum.A, Decl(type.ts, 0, 18))
B = "b"
>B : Symbol(Enum.B, Decl(type.ts, 1, 10))
}
export type Type = { x?: { [Enum.A]: 0 } };
>Type : Symbol(Type, Decl(type.ts, 3, 1))
>x : Symbol(x, Decl(type.ts, 5, 20))
>[Enum.A] : Symbol([Enum.A], Decl(type.ts, 5, 26))
>Enum.A : Symbol(Enum.A, Decl(type.ts, 0, 18))
>Enum : Symbol(Enum, Decl(type.ts, 0, 0))
>A : Symbol(Enum.A, Decl(type.ts, 0, 18))
=== index.ts ===
import { type Type } from "./type";
>Type : Symbol(Type, Decl(index.ts, 0, 8))
export const foo = { ...({} as Type) };
>foo : Symbol(foo, Decl(index.ts, 2, 12))
>Type : Symbol(Type, Decl(index.ts, 0, 8))

View File

@ -0,0 +1,51 @@
//// [tests/cases/compiler/declarationEmitComputedPropertyNameEnum1.ts] ////
=== type.ts ===
export enum Enum {
>Enum : Enum
> : ^^^^
A = "a",
>A : Enum.A
> : ^^^^^^
>"a" : "a"
> : ^^^
B = "b"
>B : Enum.B
> : ^^^^^^
>"b" : "b"
> : ^^^
}
export type Type = { x?: { [Enum.A]: 0 } };
>Type : Type
> : ^^^^
>x : { a: 0; } | undefined
> : ^^^^^ ^^^^^^^^^^^^^^^
>[Enum.A] : 0
> : ^
>Enum.A : Enum.A
> : ^^^^^^
>Enum : typeof Enum
> : ^^^^^^^^^^^
>A : Enum.A
> : ^^^^^^
=== index.ts ===
import { type Type } from "./type";
>Type : any
> : ^^^
export const foo = { ...({} as Type) };
>foo : { x?: { a: 0; }; }
> : ^^^^^^ ^^^
>{ ...({} as Type) } : { x?: { a: 0; }; }
> : ^^^^^^ ^^^
>({} as Type) : Type
> : ^^^^
>{} as Type : Type
> : ^^^^
>{} : {}
> : ^^

View File

@ -0,0 +1,16 @@
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.
type.ts(1,29): error TS2304: Cannot find name 'Enum'.
==== type.ts (2 errors) ====
export type Type = { x?: { [Enum.A]: 0 } };
~~~~~~~~
!!! 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.
~~~~
!!! error TS2304: Cannot find name 'Enum'.
==== index.ts (0 errors) ====
import { type Type } from "./type";
export const foo = { ...({} as Type) };

View File

@ -0,0 +1,23 @@
//// [tests/cases/compiler/declarationEmitComputedPropertyNameEnum2.ts] ////
//// [type.ts]
export type Type = { x?: { [Enum.A]: 0 } };
//// [index.ts]
import { type Type } from "./type";
export const foo = { ...({} as Type) };
//// [type.d.ts]
export type Type = {
x?: {};
};
//// [index.d.ts]
export declare const foo: {
x?: {
[Enum.A]: 0;
};
};

View File

@ -0,0 +1,16 @@
//// [tests/cases/compiler/declarationEmitComputedPropertyNameEnum2.ts] ////
=== type.ts ===
export type Type = { x?: { [Enum.A]: 0 } };
>Type : Symbol(Type, Decl(type.ts, 0, 0))
>x : Symbol(x, Decl(type.ts, 0, 20))
>[Enum.A] : Symbol([Enum.A], Decl(type.ts, 0, 26))
=== index.ts ===
import { type Type } from "./type";
>Type : Symbol(Type, Decl(index.ts, 0, 8))
export const foo = { ...({} as Type) };
>foo : Symbol(foo, Decl(index.ts, 2, 12))
>Type : Symbol(Type, Decl(index.ts, 0, 8))

View File

@ -0,0 +1,34 @@
//// [tests/cases/compiler/declarationEmitComputedPropertyNameEnum2.ts] ////
=== type.ts ===
export type Type = { x?: { [Enum.A]: 0 } };
>Type : Type
> : ^^^^
>x : {} | undefined
> : ^^^^^^^^^^^^^^
>[Enum.A] : 0
> : ^
>Enum.A : any
> : ^^^
>Enum : any
> : ^^^
>A : any
> : ^^^
=== index.ts ===
import { type Type } from "./type";
>Type : any
> : ^^^
export const foo = { ...({} as Type) };
>foo : { x?: { [Enum.A]: 0; }; }
> : ^^^^^^ ^^^
>{ ...({} as Type) } : { x?: { [Enum.A]: 0; }; }
> : ^^^^^^ ^^^
>({} as Type) : Type
> : ^^^^
>{} as Type : Type
> : ^^^^
>{} : {}
> : ^^

View File

@ -0,0 +1,22 @@
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.
type.ts(7,28): error TS2464: A computed property name must be of type 'string', 'number', 'symbol', or 'any'.
==== type.ts (2 errors) ====
export namespace Foo {
export enum Enum {
A = "a",
B = "b",
}
}
export type Type = { x?: { [Foo.Enum]: 0 } };
~~~~~~~~~~
!!! 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.
~~~~~~~~~~
!!! error TS2464: A computed property name must be of type 'string', 'number', 'symbol', or 'any'.
==== index.ts (0 errors) ====
import { type Type } from "./type";
export const foo = { ...({} as Type) };

View File

@ -0,0 +1,33 @@
//// [tests/cases/compiler/declarationEmitComputedPropertyNameEnum3.ts] ////
//// [type.ts]
export namespace Foo {
export enum Enum {
A = "a",
B = "b",
}
}
export type Type = { x?: { [Foo.Enum]: 0 } };
//// [index.ts]
import { type Type } from "./type";
export const foo = { ...({} as Type) };
//// [type.d.ts]
export declare namespace Foo {
enum Enum {
A = "a",
B = "b"
}
}
export type Type = {
x?: {};
};
//// [index.d.ts]
export declare const foo: {
x?: {};
};

View File

@ -0,0 +1,32 @@
//// [tests/cases/compiler/declarationEmitComputedPropertyNameEnum3.ts] ////
=== type.ts ===
export namespace Foo {
>Foo : Symbol(Foo, Decl(type.ts, 0, 0))
export enum Enum {
>Enum : Symbol(Enum, Decl(type.ts, 0, 22))
A = "a",
>A : Symbol(Enum.A, Decl(type.ts, 1, 20))
B = "b",
>B : Symbol(Enum.B, Decl(type.ts, 2, 12))
}
}
export type Type = { x?: { [Foo.Enum]: 0 } };
>Type : Symbol(Type, Decl(type.ts, 5, 1))
>x : Symbol(x, Decl(type.ts, 6, 20))
>[Foo.Enum] : Symbol([Foo.Enum], Decl(type.ts, 6, 26))
>Foo.Enum : Symbol(Foo.Enum, Decl(type.ts, 0, 22))
>Foo : Symbol(Foo, Decl(type.ts, 0, 0))
>Enum : Symbol(Foo.Enum, Decl(type.ts, 0, 22))
=== index.ts ===
import { type Type } from "./type";
>Type : Symbol(Type, Decl(index.ts, 0, 8))
export const foo = { ...({} as Type) };
>foo : Symbol(foo, Decl(index.ts, 2, 12))
>Type : Symbol(Type, Decl(index.ts, 0, 8))

View File

@ -0,0 +1,55 @@
//// [tests/cases/compiler/declarationEmitComputedPropertyNameEnum3.ts] ////
=== type.ts ===
export namespace Foo {
>Foo : typeof Foo
> : ^^^^^^^^^^
export enum Enum {
>Enum : Enum
> : ^^^^
A = "a",
>A : Enum.A
> : ^^^^^^
>"a" : "a"
> : ^^^
B = "b",
>B : Enum.B
> : ^^^^^^
>"b" : "b"
> : ^^^
}
}
export type Type = { x?: { [Foo.Enum]: 0 } };
>Type : Type
> : ^^^^
>x : {} | undefined
> : ^^^^^^^^^^^^^^
>[Foo.Enum] : 0
> : ^
>Foo.Enum : typeof Foo.Enum
> : ^^^^^^^^^^^^^^^
>Foo : typeof Foo
> : ^^^^^^^^^^
>Enum : typeof Foo.Enum
> : ^^^^^^^^^^^^^^^
=== index.ts ===
import { type Type } from "./type";
>Type : any
> : ^^^
export const foo = { ...({} as Type) };
>foo : { x?: {}; }
> : ^^^^^^ ^^^
>{ ...({} as Type) } : { x?: {}; }
> : ^^^^^^ ^^^
>({} as Type) : Type
> : ^^^^
>{} as Type : Type
> : ^^^^
>{} : {}
> : ^^

View File

@ -0,0 +1,16 @@
index.ts(3,14): error TS4023: Exported variable 'foo' has or is using name 'Foo' from external module "type" but cannot be named.
==== type.ts (0 errors) ====
export namespace Foo {
export const sym = Symbol();
}
export type Type = { x?: { [Foo.sym]: 0 } };
==== index.ts (1 errors) ====
import { type Type } from "./type";
export const foo = { ...({} as Type) };
~~~
!!! error TS4023: Exported variable 'foo' has or is using name 'Foo' from external module "type" but cannot be named.

View File

@ -0,0 +1,25 @@
//// [tests/cases/compiler/declarationEmitComputedPropertyNameSymbol1.ts] ////
//// [type.ts]
export namespace Foo {
export const sym = Symbol();
}
export type Type = { x?: { [Foo.sym]: 0 } };
//// [index.ts]
import { type Type } from "./type";
export const foo = { ...({} as Type) };
//// [type.d.ts]
export declare namespace Foo {
const sym: unique symbol;
}
export type Type = {
x?: {
[Foo.sym]: 0;
};
};

View File

@ -0,0 +1,26 @@
//// [tests/cases/compiler/declarationEmitComputedPropertyNameSymbol1.ts] ////
=== type.ts ===
export namespace Foo {
>Foo : Symbol(Foo, Decl(type.ts, 0, 0))
export const sym = Symbol();
>sym : Symbol(sym, Decl(type.ts, 1, 14))
>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, --, --))
}
export type Type = { x?: { [Foo.sym]: 0 } };
>Type : Symbol(Type, Decl(type.ts, 2, 1))
>x : Symbol(x, Decl(type.ts, 3, 20))
>[Foo.sym] : Symbol([Foo.sym], Decl(type.ts, 3, 26))
>Foo.sym : Symbol(Foo.sym, Decl(type.ts, 1, 14))
>Foo : Symbol(Foo, Decl(type.ts, 0, 0))
>sym : Symbol(Foo.sym, Decl(type.ts, 1, 14))
=== index.ts ===
import { type Type } from "./type";
>Type : Symbol(Type, Decl(index.ts, 0, 8))
export const foo = { ...({} as Type) };
>foo : Symbol(foo, Decl(index.ts, 2, 12))
>Type : Symbol(Type, Decl(index.ts, 0, 8))

View File

@ -0,0 +1,46 @@
//// [tests/cases/compiler/declarationEmitComputedPropertyNameSymbol1.ts] ////
=== type.ts ===
export namespace Foo {
>Foo : typeof Foo
> : ^^^^^^^^^^
export const sym = Symbol();
>sym : unique symbol
> : ^^^^^^^^^^^^^
>Symbol() : unique symbol
> : ^^^^^^^^^^^^^
>Symbol : SymbolConstructor
> : ^^^^^^^^^^^^^^^^^
}
export type Type = { x?: { [Foo.sym]: 0 } };
>Type : Type
> : ^^^^
>x : { [Foo.sym]: 0; } | undefined
> : ^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^
>[Foo.sym] : 0
> : ^
>Foo.sym : unique symbol
> : ^^^^^^^^^^^^^
>Foo : typeof Foo
> : ^^^^^^^^^^
>sym : unique symbol
> : ^^^^^^^^^^^^^
=== index.ts ===
import { type Type } from "./type";
>Type : any
> : ^^^
export const foo = { ...({} as Type) };
>foo : { x?: { [Foo.sym]: 0; }; }
> : ^^^^^^ ^^^
>{ ...({} as Type) } : { x?: { [Foo.sym]: 0; }; }
> : ^^^^^^ ^^^
>({} as Type) : Type
> : ^^^^
>{} as Type : Type
> : ^^^^
>{} : {}
> : ^^

View File

@ -0,0 +1,16 @@
index.ts(3,14): error TS4023: Exported variable 'foo' has or is using name 'Foo' from external module "type" but cannot be named.
==== type.ts (0 errors) ====
namespace Foo {
export const sym = Symbol();
}
export type Type = { x?: { [Foo.sym]: 0 } };
==== index.ts (1 errors) ====
import { type Type } from "./type";
export const foo = { ...({} as Type) };
~~~
!!! error TS4023: Exported variable 'foo' has or is using name 'Foo' from external module "type" but cannot be named.

View File

@ -0,0 +1,26 @@
//// [tests/cases/compiler/declarationEmitComputedPropertyNameSymbol2.ts] ////
//// [type.ts]
namespace Foo {
export const sym = Symbol();
}
export type Type = { x?: { [Foo.sym]: 0 } };
//// [index.ts]
import { type Type } from "./type";
export const foo = { ...({} as Type) };
//// [type.d.ts]
declare namespace Foo {
const sym: unique symbol;
}
export type Type = {
x?: {
[Foo.sym]: 0;
};
};
export {};

View File

@ -0,0 +1,26 @@
//// [tests/cases/compiler/declarationEmitComputedPropertyNameSymbol2.ts] ////
=== type.ts ===
namespace Foo {
>Foo : Symbol(Foo, Decl(type.ts, 0, 0))
export const sym = Symbol();
>sym : Symbol(sym, Decl(type.ts, 1, 14))
>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, --, --))
}
export type Type = { x?: { [Foo.sym]: 0 } };
>Type : Symbol(Type, Decl(type.ts, 2, 1))
>x : Symbol(x, Decl(type.ts, 3, 20))
>[Foo.sym] : Symbol([Foo.sym], Decl(type.ts, 3, 26))
>Foo.sym : Symbol(Foo.sym, Decl(type.ts, 1, 14))
>Foo : Symbol(Foo, Decl(type.ts, 0, 0))
>sym : Symbol(Foo.sym, Decl(type.ts, 1, 14))
=== index.ts ===
import { type Type } from "./type";
>Type : Symbol(Type, Decl(index.ts, 0, 8))
export const foo = { ...({} as Type) };
>foo : Symbol(foo, Decl(index.ts, 2, 12))
>Type : Symbol(Type, Decl(index.ts, 0, 8))

View File

@ -0,0 +1,46 @@
//// [tests/cases/compiler/declarationEmitComputedPropertyNameSymbol2.ts] ////
=== type.ts ===
namespace Foo {
>Foo : typeof Foo
> : ^^^^^^^^^^
export const sym = Symbol();
>sym : unique symbol
> : ^^^^^^^^^^^^^
>Symbol() : unique symbol
> : ^^^^^^^^^^^^^
>Symbol : SymbolConstructor
> : ^^^^^^^^^^^^^^^^^
}
export type Type = { x?: { [Foo.sym]: 0 } };
>Type : Type
> : ^^^^
>x : { [Foo.sym]: 0; } | undefined
> : ^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^
>[Foo.sym] : 0
> : ^
>Foo.sym : unique symbol
> : ^^^^^^^^^^^^^
>Foo : typeof Foo
> : ^^^^^^^^^^
>sym : unique symbol
> : ^^^^^^^^^^^^^
=== index.ts ===
import { type Type } from "./type";
>Type : any
> : ^^^
export const foo = { ...({} as Type) };
>foo : { x?: { [Foo.sym]: 0; }; }
> : ^^^^^^ ^^^
>{ ...({} as Type) } : { x?: { [Foo.sym]: 0; }; }
> : ^^^^^^ ^^^
>({} as Type) : Type
> : ^^^^
>{} as Type : Type
> : ^^^^
>{} : {}
> : ^^

View File

@ -0,0 +1,16 @@
// @strict: true
// @declaration: true
// @emitDeclarationOnly: true
// @filename: type.ts
export enum Enum {
A = "a",
B = "b"
}
export type Type = { x?: { [Enum.A]: 0 } };
// @filename: index.ts
import { type Type } from "./type";
export const foo = { ...({} as Type) };

View File

@ -0,0 +1,11 @@
// @strict: true
// @declaration: true
// @emitDeclarationOnly: true
// @filename: type.ts
export type Type = { x?: { [Enum.A]: 0 } };
// @filename: index.ts
import { type Type } from "./type";
export const foo = { ...({} as Type) };

View File

@ -0,0 +1,17 @@
// @strict: true
// @declaration: true
// @emitDeclarationOnly: true
// @filename: type.ts
export namespace Foo {
export enum Enum {
A = "a",
B = "b",
}
}
export type Type = { x?: { [Foo.Enum]: 0 } };
// @filename: index.ts
import { type Type } from "./type";
export const foo = { ...({} as Type) };

View File

@ -0,0 +1,15 @@
// @strict: true
// @lib: esnext
// @declaration: true
// @emitDeclarationOnly: true
// @filename: type.ts
export namespace Foo {
export const sym = Symbol();
}
export type Type = { x?: { [Foo.sym]: 0 } };
// @filename: index.ts
import { type Type } from "./type";
export const foo = { ...({} as Type) };

View File

@ -0,0 +1,15 @@
// @strict: true
// @lib: esnext
// @declaration: true
// @emitDeclarationOnly: true
// @filename: type.ts
namespace Foo {
export const sym = Symbol();
}
export type Type = { x?: { [Foo.sym]: 0 } };
// @filename: index.ts
import { type Type } from "./type";
export const foo = { ...({} as Type) };