diff --git a/internal/transformers/declarations/transform.go b/internal/transformers/declarations/transform.go index c16b75baef..7d36b95780 100644 --- a/internal/transformers/declarations/transform.go +++ b/internal/transformers/declarations/transform.go @@ -2173,6 +2173,10 @@ func (tx *DeclarationTransformer) transformJSDocOptionalType(input *ast.JSDocOpt } func (tx *DeclarationTransformer) getNameExpressionPreferringIdentifier(nameExpr *ast.Node) *ast.Node { + if ast.IsNumericLiteral(nameExpr) { + // Numeric property names are string properties in JS; convert to string literal + nameExpr = tx.Factory().NewStringLiteral(nameExpr.Text(), ast.TokenFlagsNone) + } if ast.IsStringLiteralLike(nameExpr) && scanner.IsIdentifierText(nameExpr.Text(), core.LanguageVariantStandard) { result := tx.Factory().NewIdentifier(nameExpr.Text()) // prefer non-string literal names where possible kwKind := scanner.IdentifierToKeywordKind(result.AsIdentifier()) diff --git a/testdata/baselines/reference/compiler/numericExportNameDeclaration.js b/testdata/baselines/reference/compiler/numericExportNameDeclaration.js new file mode 100644 index 0000000000..c8f94b58bc --- /dev/null +++ b/testdata/baselines/reference/compiler/numericExportNameDeclaration.js @@ -0,0 +1,41 @@ +//// [tests/cases/compiler/numericExportNameDeclaration.ts] //// + +//// [bug.js] +exports[1] = 2; +module.exports[1] = 2; +Object.defineProperty(exports, 1, {}); + + + + +//// [bug.d.ts] +declare const _exported: any; +export { _exported as "1" }; +declare const _exported_1: any; +export { _exported_1 as "1" }; +declare const _exported_2: any; +export { _exported_2 as "1" }; + + +//// [DtsFileErrors] + + +bug.d.ts(2,23): error TS2300: Duplicate identifier '"1"'. +bug.d.ts(4,25): error TS2300: Duplicate identifier '"1"'. +bug.d.ts(6,25): error TS2300: Duplicate identifier '"1"'. + + +==== bug.d.ts (3 errors) ==== + declare const _exported: any; + export { _exported as "1" }; + ~~~ +!!! error TS2300: Duplicate identifier '"1"'. + declare const _exported_1: any; + export { _exported_1 as "1" }; + ~~~ +!!! error TS2300: Duplicate identifier '"1"'. + declare const _exported_2: any; + export { _exported_2 as "1" }; + ~~~ +!!! error TS2300: Duplicate identifier '"1"'. + \ No newline at end of file diff --git a/testdata/baselines/reference/compiler/numericExportNameDeclaration.symbols b/testdata/baselines/reference/compiler/numericExportNameDeclaration.symbols new file mode 100644 index 0000000000..4d1b3998f1 --- /dev/null +++ b/testdata/baselines/reference/compiler/numericExportNameDeclaration.symbols @@ -0,0 +1,19 @@ +//// [tests/cases/compiler/numericExportNameDeclaration.ts] //// + +=== bug.js === +exports[1] = 2; +>exports : Symbol(exports, Decl(bug.js, 0, 0)) +>1 : Symbol(1, Decl(bug.js, 0, 0), Decl(bug.js, 0, 15), Decl(bug.js, 1, 22)) + +module.exports[1] = 2; +>module.exports : Symbol(exports, Decl(bug.js, 0, 0)) +>module : Symbol(module, Decl(bug.js, 0, 0)) +>exports : Symbol(exports, Decl(bug.js, 0, 0)) +>1 : Symbol(1, Decl(bug.js, 0, 0), Decl(bug.js, 0, 15), Decl(bug.js, 1, 22)) + +Object.defineProperty(exports, 1, {}); +>Object.defineProperty : Symbol(ObjectConstructor.defineProperty, Decl(lib.es5.d.ts, --, --)) +>Object : Symbol(Object, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) +>defineProperty : Symbol(ObjectConstructor.defineProperty, Decl(lib.es5.d.ts, --, --)) +>exports : Symbol(exports, Decl(bug.js, 0, 0)) + diff --git a/testdata/baselines/reference/compiler/numericExportNameDeclaration.types b/testdata/baselines/reference/compiler/numericExportNameDeclaration.types new file mode 100644 index 0000000000..00507e0eb4 --- /dev/null +++ b/testdata/baselines/reference/compiler/numericExportNameDeclaration.types @@ -0,0 +1,28 @@ +//// [tests/cases/compiler/numericExportNameDeclaration.ts] //// + +=== bug.js === +exports[1] = 2; +>exports[1] = 2 : 2 +>exports[1] : any +>exports : typeof import("./bug") +>1 : 1 +>2 : 2 + +module.exports[1] = 2; +>module.exports[1] = 2 : 2 +>module.exports[1] : error +>module.exports : typeof import("./bug") +>module : { exports: typeof import("./bug"); } +>exports : typeof import("./bug") +>1 : 1 +>2 : 2 + +Object.defineProperty(exports, 1, {}); +>Object.defineProperty(exports, 1, {}) : typeof import("./bug") +>Object.defineProperty : (o: T, p: PropertyKey, attributes: PropertyDescriptor & ThisType) => T +>Object : ObjectConstructor +>defineProperty : (o: T, p: PropertyKey, attributes: PropertyDescriptor & ThisType) => T +>exports : typeof import("./bug") +>1 : 1 +>{} : {} + diff --git a/testdata/tests/cases/compiler/numericExportNameDeclaration.ts b/testdata/tests/cases/compiler/numericExportNameDeclaration.ts new file mode 100644 index 0000000000..8255adf5d8 --- /dev/null +++ b/testdata/tests/cases/compiler/numericExportNameDeclaration.ts @@ -0,0 +1,8 @@ +// @declaration: true +// @emitDeclarationOnly: true +// @allowJs: true + +// @filename: bug.js +exports[1] = 2; +module.exports[1] = 2; +Object.defineProperty(exports, 1, {});