From 3880fce2499b913fec8103028d9c15ea1973e824 Mon Sep 17 00:00:00 2001 From: Oleksandr T Date: Wed, 1 Feb 2023 21:44:22 +0200 Subject: [PATCH] fix(52455): destructuring function props with "enum" as property name breaks .d.ts (#52544) --- src/compiler/transformers/declarations.ts | 3 +- .../declarationEmitKeywordDestructuring.js | 109 ++++++++++++++++++ ...eclarationEmitKeywordDestructuring.symbols | 79 +++++++++++++ .../declarationEmitKeywordDestructuring.types | 74 ++++++++++++ .../declarationEmitKeywordDestructuring.ts | 30 +++++ 5 files changed, 294 insertions(+), 1 deletion(-) create mode 100644 tests/baselines/reference/declarationEmitKeywordDestructuring.js create mode 100644 tests/baselines/reference/declarationEmitKeywordDestructuring.symbols create mode 100644 tests/baselines/reference/declarationEmitKeywordDestructuring.types create mode 100644 tests/cases/compiler/declarationEmitKeywordDestructuring.ts diff --git a/src/compiler/transformers/declarations.ts b/src/compiler/transformers/declarations.ts index c9c8fb39df3..6f8b17aaca3 100644 --- a/src/compiler/transformers/declarations.ts +++ b/src/compiler/transformers/declarations.ts @@ -113,6 +113,7 @@ import { isFunctionLike, isGlobalScopeAugmentation, isIdentifier, + isIdentifierANonContextualKeyword, isImportDeclaration, isImportEqualsDeclaration, isIndexSignatureDeclaration, @@ -695,7 +696,7 @@ export function transformDeclarations(context: TransformationContext) { if (elem.kind === SyntaxKind.OmittedExpression) { return elem; } - if (elem.propertyName && isIdentifier(elem.propertyName) && isIdentifier(elem.name) && !elem.symbol.isReferenced) { + if (elem.propertyName && isIdentifier(elem.propertyName) && isIdentifier(elem.name) && !elem.symbol.isReferenced && !isIdentifierANonContextualKeyword(elem.propertyName)) { // Unnecessary property renaming is forbidden in types, so remove renaming return factory.updateBindingElement( elem, diff --git a/tests/baselines/reference/declarationEmitKeywordDestructuring.js b/tests/baselines/reference/declarationEmitKeywordDestructuring.js new file mode 100644 index 00000000000..bd4e444e186 --- /dev/null +++ b/tests/baselines/reference/declarationEmitKeywordDestructuring.js @@ -0,0 +1,109 @@ +//// [declarationEmitKeywordDestructuring.ts] +type P = { + enum: boolean; + function: boolean; + abstract: boolean; + async: boolean; + await: boolean; + one: boolean; +}; + +function f1({ enum: _enum, ...rest }: P) { + return rest; +} + +function f2({ function: _function, ...rest }: P) { + return rest; +} + +function f3({ abstract: _abstract, ...rest }: P) { + return rest; +} + +function f4({ async: _async, ...rest }: P) { + return rest; +} + +function f5({ await: _await, ...rest }: P) { + return rest; +} + + +//// [declarationEmitKeywordDestructuring.js] +var __rest = (this && this.__rest) || function (s, e) { + var t = {}; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) + t[p] = s[p]; + if (s != null && typeof Object.getOwnPropertySymbols === "function") + for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) { + if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) + t[p[i]] = s[p[i]]; + } + return t; +}; +function f1(_a) { + var _enum = _a.enum, rest = __rest(_a, ["enum"]); + return rest; +} +function f2(_a) { + var _function = _a.function, rest = __rest(_a, ["function"]); + return rest; +} +function f3(_a) { + var _abstract = _a.abstract, rest = __rest(_a, ["abstract"]); + return rest; +} +function f4(_a) { + var _async = _a.async, rest = __rest(_a, ["async"]); + return rest; +} +function f5(_a) { + var _await = _a.await, rest = __rest(_a, ["await"]); + return rest; +} + + +//// [declarationEmitKeywordDestructuring.d.ts] +type P = { + enum: boolean; + function: boolean; + abstract: boolean; + async: boolean; + await: boolean; + one: boolean; +}; +declare function f1({ enum: _enum, ...rest }: P): { + function: boolean; + abstract: boolean; + async: boolean; + await: boolean; + one: boolean; +}; +declare function f2({ function: _function, ...rest }: P): { + enum: boolean; + abstract: boolean; + async: boolean; + await: boolean; + one: boolean; +}; +declare function f3({ abstract, ...rest }: P): { + enum: boolean; + function: boolean; + async: boolean; + await: boolean; + one: boolean; +}; +declare function f4({ async, ...rest }: P): { + enum: boolean; + function: boolean; + abstract: boolean; + await: boolean; + one: boolean; +}; +declare function f5({ await, ...rest }: P): { + enum: boolean; + function: boolean; + abstract: boolean; + async: boolean; + one: boolean; +}; diff --git a/tests/baselines/reference/declarationEmitKeywordDestructuring.symbols b/tests/baselines/reference/declarationEmitKeywordDestructuring.symbols new file mode 100644 index 00000000000..8c5c6437b7a --- /dev/null +++ b/tests/baselines/reference/declarationEmitKeywordDestructuring.symbols @@ -0,0 +1,79 @@ +=== tests/cases/compiler/declarationEmitKeywordDestructuring.ts === +type P = { +>P : Symbol(P, Decl(declarationEmitKeywordDestructuring.ts, 0, 0)) + + enum: boolean; +>enum : Symbol(enum, Decl(declarationEmitKeywordDestructuring.ts, 0, 10)) + + function: boolean; +>function : Symbol(function, Decl(declarationEmitKeywordDestructuring.ts, 1, 18)) + + abstract: boolean; +>abstract : Symbol(abstract, Decl(declarationEmitKeywordDestructuring.ts, 2, 22)) + + async: boolean; +>async : Symbol(async, Decl(declarationEmitKeywordDestructuring.ts, 3, 22)) + + await: boolean; +>await : Symbol(await, Decl(declarationEmitKeywordDestructuring.ts, 4, 19)) + + one: boolean; +>one : Symbol(one, Decl(declarationEmitKeywordDestructuring.ts, 5, 19)) + +}; + +function f1({ enum: _enum, ...rest }: P) { +>f1 : Symbol(f1, Decl(declarationEmitKeywordDestructuring.ts, 7, 2)) +>enum : Symbol(enum, Decl(declarationEmitKeywordDestructuring.ts, 0, 10)) +>_enum : Symbol(_enum, Decl(declarationEmitKeywordDestructuring.ts, 9, 13)) +>rest : Symbol(rest, Decl(declarationEmitKeywordDestructuring.ts, 9, 26)) +>P : Symbol(P, Decl(declarationEmitKeywordDestructuring.ts, 0, 0)) + + return rest; +>rest : Symbol(rest, Decl(declarationEmitKeywordDestructuring.ts, 9, 26)) +} + +function f2({ function: _function, ...rest }: P) { +>f2 : Symbol(f2, Decl(declarationEmitKeywordDestructuring.ts, 11, 1)) +>function : Symbol(function, Decl(declarationEmitKeywordDestructuring.ts, 1, 18)) +>_function : Symbol(_function, Decl(declarationEmitKeywordDestructuring.ts, 13, 13)) +>rest : Symbol(rest, Decl(declarationEmitKeywordDestructuring.ts, 13, 34)) +>P : Symbol(P, Decl(declarationEmitKeywordDestructuring.ts, 0, 0)) + + return rest; +>rest : Symbol(rest, Decl(declarationEmitKeywordDestructuring.ts, 13, 34)) +} + +function f3({ abstract: _abstract, ...rest }: P) { +>f3 : Symbol(f3, Decl(declarationEmitKeywordDestructuring.ts, 15, 1)) +>abstract : Symbol(abstract, Decl(declarationEmitKeywordDestructuring.ts, 2, 22)) +>_abstract : Symbol(_abstract, Decl(declarationEmitKeywordDestructuring.ts, 17, 13)) +>rest : Symbol(rest, Decl(declarationEmitKeywordDestructuring.ts, 17, 34)) +>P : Symbol(P, Decl(declarationEmitKeywordDestructuring.ts, 0, 0)) + + return rest; +>rest : Symbol(rest, Decl(declarationEmitKeywordDestructuring.ts, 17, 34)) +} + +function f4({ async: _async, ...rest }: P) { +>f4 : Symbol(f4, Decl(declarationEmitKeywordDestructuring.ts, 19, 1)) +>async : Symbol(async, Decl(declarationEmitKeywordDestructuring.ts, 3, 22)) +>_async : Symbol(_async, Decl(declarationEmitKeywordDestructuring.ts, 21, 13)) +>rest : Symbol(rest, Decl(declarationEmitKeywordDestructuring.ts, 21, 28)) +>P : Symbol(P, Decl(declarationEmitKeywordDestructuring.ts, 0, 0)) + + return rest; +>rest : Symbol(rest, Decl(declarationEmitKeywordDestructuring.ts, 21, 28)) +} + +function f5({ await: _await, ...rest }: P) { +>f5 : Symbol(f5, Decl(declarationEmitKeywordDestructuring.ts, 23, 1)) +>await : Symbol(await, Decl(declarationEmitKeywordDestructuring.ts, 4, 19)) +>_await : Symbol(_await, Decl(declarationEmitKeywordDestructuring.ts, 25, 13)) +>rest : Symbol(rest, Decl(declarationEmitKeywordDestructuring.ts, 25, 28)) +>P : Symbol(P, Decl(declarationEmitKeywordDestructuring.ts, 0, 0)) + + return rest; +>rest : Symbol(rest, Decl(declarationEmitKeywordDestructuring.ts, 25, 28)) +} + diff --git a/tests/baselines/reference/declarationEmitKeywordDestructuring.types b/tests/baselines/reference/declarationEmitKeywordDestructuring.types new file mode 100644 index 00000000000..d3aff327473 --- /dev/null +++ b/tests/baselines/reference/declarationEmitKeywordDestructuring.types @@ -0,0 +1,74 @@ +=== tests/cases/compiler/declarationEmitKeywordDestructuring.ts === +type P = { +>P : { enum: boolean; function: boolean; abstract: boolean; async: boolean; await: boolean; one: boolean; } + + enum: boolean; +>enum : boolean + + function: boolean; +>function : boolean + + abstract: boolean; +>abstract : boolean + + async: boolean; +>async : boolean + + await: boolean; +>await : boolean + + one: boolean; +>one : boolean + +}; + +function f1({ enum: _enum, ...rest }: P) { +>f1 : ({ enum: _enum, ...rest }: P) => { function: boolean; abstract: boolean; async: boolean; await: boolean; one: boolean; } +>enum : any +>_enum : boolean +>rest : { function: boolean; abstract: boolean; async: boolean; await: boolean; one: boolean; } + + return rest; +>rest : { function: boolean; abstract: boolean; async: boolean; await: boolean; one: boolean; } +} + +function f2({ function: _function, ...rest }: P) { +>f2 : ({ function: _function, ...rest }: P) => { enum: boolean; abstract: boolean; async: boolean; await: boolean; one: boolean; } +>function : any +>_function : boolean +>rest : { enum: boolean; abstract: boolean; async: boolean; await: boolean; one: boolean; } + + return rest; +>rest : { enum: boolean; abstract: boolean; async: boolean; await: boolean; one: boolean; } +} + +function f3({ abstract: _abstract, ...rest }: P) { +>f3 : ({ abstract: _abstract, ...rest }: P) => { enum: boolean; function: boolean; async: boolean; await: boolean; one: boolean; } +>abstract : any +>_abstract : boolean +>rest : { enum: boolean; function: boolean; async: boolean; await: boolean; one: boolean; } + + return rest; +>rest : { enum: boolean; function: boolean; async: boolean; await: boolean; one: boolean; } +} + +function f4({ async: _async, ...rest }: P) { +>f4 : ({ async: _async, ...rest }: P) => { enum: boolean; function: boolean; abstract: boolean; await: boolean; one: boolean; } +>async : any +>_async : boolean +>rest : { enum: boolean; function: boolean; abstract: boolean; await: boolean; one: boolean; } + + return rest; +>rest : { enum: boolean; function: boolean; abstract: boolean; await: boolean; one: boolean; } +} + +function f5({ await: _await, ...rest }: P) { +>f5 : ({ await: _await, ...rest }: P) => { enum: boolean; function: boolean; abstract: boolean; async: boolean; one: boolean; } +>await : any +>_await : boolean +>rest : { enum: boolean; function: boolean; abstract: boolean; async: boolean; one: boolean; } + + return rest; +>rest : { enum: boolean; function: boolean; abstract: boolean; async: boolean; one: boolean; } +} + diff --git a/tests/cases/compiler/declarationEmitKeywordDestructuring.ts b/tests/cases/compiler/declarationEmitKeywordDestructuring.ts new file mode 100644 index 00000000000..72015314fc6 --- /dev/null +++ b/tests/cases/compiler/declarationEmitKeywordDestructuring.ts @@ -0,0 +1,30 @@ +// @declaration: true + +type P = { + enum: boolean; + function: boolean; + abstract: boolean; + async: boolean; + await: boolean; + one: boolean; +}; + +function f1({ enum: _enum, ...rest }: P) { + return rest; +} + +function f2({ function: _function, ...rest }: P) { + return rest; +} + +function f3({ abstract: _abstract, ...rest }: P) { + return rest; +} + +function f4({ async: _async, ...rest }: P) { + return rest; +} + +function f5({ await: _await, ...rest }: P) { + return rest; +}