From 4629db6b0dbc88c6d7f7e8eb23996138f96dbda9 Mon Sep 17 00:00:00 2001 From: Lucas Azzola Date: Sun, 7 May 2017 01:00:26 +1000 Subject: [PATCH] TypeScript: improve handling of computed properties (#1532) * fix(typescript): improve handling of computed properties * test(typescript): add Symbol computed property test * fix(typescript): do not print brackets for literals --- src/fast-path.js | 8 ++++ src/printer.js | 18 ++++++-- .../compiler/__snapshots__/jsfmt.spec.js.snap | 42 ++++++++++++++----- .../compiler/indexSignatureWithInitializer.ts | 8 ++++ .../__snapshots__/jsfmt.spec.js.snap | 39 +++++++++++++++++ .../custom/computedProperties/jsfmt.spec.js | 1 + .../custom/computedProperties/string.ts | 7 ++++ .../custom/computedProperties/symbol.ts | 7 ++++ 8 files changed, 115 insertions(+), 15 deletions(-) create mode 100644 tests/typescript/compiler/indexSignatureWithInitializer.ts create mode 100644 tests/typescript/custom/computedProperties/__snapshots__/jsfmt.spec.js.snap create mode 100644 tests/typescript/custom/computedProperties/jsfmt.spec.js create mode 100644 tests/typescript/custom/computedProperties/string.ts create mode 100644 tests/typescript/custom/computedProperties/symbol.ts diff --git a/src/fast-path.js b/src/fast-path.js index 5e982383..08612351 100644 --- a/src/fast-path.js +++ b/src/fast-path.js @@ -445,6 +445,14 @@ FPp.needsParens = function() { case "AssignmentExpression": if (parent.type === "ArrowFunctionExpression" && parent.body === node) { return true; + } else if ( + parent.type === "ClassProperty" && + parent.key === node && + parent.computed + ) { + return false; + } else if (parent.type === "TSPropertySignature" && parent.name === node) { + return false; } else if ( parent.type === "ForStatement" && (parent.init === node || parent.update === node) diff --git a/src/printer.js b/src/printer.js index 5b129629..bbff7bf4 100644 --- a/src/printer.js +++ b/src/printer.js @@ -2093,10 +2093,20 @@ function genericPrintNoParens(path, options, print, args) { case "TSArrayType": return concat([path.call(print, "elementType"), "[]"]); case "TSPropertySignature": - parts.push( - printTypeScriptModifiers(path, options, print), - path.call(print, "name") - ); + var computed = !namedTypes.Identifier.check(n.name) && + !namedTypes.Literal.check(n.name); + + parts.push(printTypeScriptModifiers(path, options, print)); + + if (computed) { + parts.push("["); + } + + parts.push(path.call(print, "name")); + + if (computed) { + parts.push("]"); + } if (n.typeAnnotation) { parts.push(": "); diff --git a/tests/typescript/compiler/__snapshots__/jsfmt.spec.js.snap b/tests/typescript/compiler/__snapshots__/jsfmt.spec.js.snap index 0d493b12..f2b65a12 100644 --- a/tests/typescript/compiler/__snapshots__/jsfmt.spec.js.snap +++ b/tests/typescript/compiler/__snapshots__/jsfmt.spec.js.snap @@ -7,17 +7,6 @@ var results = number[]; `; -exports[`commentsInterface.ts 1`] = ` -interface i2 { - foo: (/**param help*/b: number) => string; -} -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -interface i2 { - foo: (/**param help*/ b: number) => string -} - -`; - exports[`checkInfiniteExpansionTermination.ts 1`] = ` // Regression test for #1002 // Before fix this code would cause infinite loop @@ -55,6 +44,17 @@ values = values2; `; +exports[`commentsInterface.ts 1`] = ` +interface i2 { + foo: (/**param help*/b: number) => string; +} +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +interface i2 { + foo: (/**param help*/ b: number) => string +} + +`; + exports[`functionOverloadsOnGenericArity1.ts 1`] = ` // overloading on arity not allowed interface C { @@ -82,6 +82,26 @@ interface C { `; +exports[`indexSignatureWithInitializer.ts 1`] = ` +// These used to be indexers, now they are computed properties +interface I { + [x = '']: string; +} + +class C { + [x = 0]: string +}~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// These used to be indexers, now they are computed properties +interface I { + [x = ""]: string +} + +class C { + [x = 0]: string; +} + +`; + exports[`mappedTypeWithCombinedTypeMappers.ts 1`] = ` // Repro from #13351 diff --git a/tests/typescript/compiler/indexSignatureWithInitializer.ts b/tests/typescript/compiler/indexSignatureWithInitializer.ts new file mode 100644 index 00000000..f9a4aafc --- /dev/null +++ b/tests/typescript/compiler/indexSignatureWithInitializer.ts @@ -0,0 +1,8 @@ +// These used to be indexers, now they are computed properties +interface I { + [x = '']: string; +} + +class C { + [x = 0]: string +} \ No newline at end of file diff --git a/tests/typescript/custom/computedProperties/__snapshots__/jsfmt.spec.js.snap b/tests/typescript/custom/computedProperties/__snapshots__/jsfmt.spec.js.snap new file mode 100644 index 00000000..638d8d04 --- /dev/null +++ b/tests/typescript/custom/computedProperties/__snapshots__/jsfmt.spec.js.snap @@ -0,0 +1,39 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`string.ts 1`] = ` +interface I { + "string": "I"; +} + +type T = { + "string": "T"; +} +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +interface I { + "string": "I" +} + +type T = { + "string": "T" +}; + +`; + +exports[`symbol.ts 1`] = ` +interface I { + [Symbol.toStringTag]: "I"; +} + +type T = { + [Symbol.toStringTag]: "T"; +} +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +interface I { + [Symbol.toStringTag]: "I" +} + +type T = { + [Symbol.toStringTag]: "T" +}; + +`; diff --git a/tests/typescript/custom/computedProperties/jsfmt.spec.js b/tests/typescript/custom/computedProperties/jsfmt.spec.js new file mode 100644 index 00000000..bc085c48 --- /dev/null +++ b/tests/typescript/custom/computedProperties/jsfmt.spec.js @@ -0,0 +1 @@ +run_spec(__dirname, { parser: "typescript" }); diff --git a/tests/typescript/custom/computedProperties/string.ts b/tests/typescript/custom/computedProperties/string.ts new file mode 100644 index 00000000..e003c31f --- /dev/null +++ b/tests/typescript/custom/computedProperties/string.ts @@ -0,0 +1,7 @@ +interface I { + "string": "I"; +} + +type T = { + "string": "T"; +} diff --git a/tests/typescript/custom/computedProperties/symbol.ts b/tests/typescript/custom/computedProperties/symbol.ts new file mode 100644 index 00000000..5da83454 --- /dev/null +++ b/tests/typescript/custom/computedProperties/symbol.ts @@ -0,0 +1,7 @@ +interface I { + [Symbol.toStringTag]: "I"; +} + +type T = { + [Symbol.toStringTag]: "T"; +}