From 445a56dab449ebcc35ceae3edf20edbb04f4c6ec Mon Sep 17 00:00:00 2001 From: Ian Schmitz Date: Wed, 21 Nov 2018 18:57:25 -0800 Subject: [PATCH] Fix TypeScript decorator support (#5783) * Fix TypeScript decorator support * Update babel flow override * WIP --- packages/babel-preset-react-app/create.js | 11 ++++++++++- test/fixtures/typescript/src/App.test.ts | 6 ++++++ test/fixtures/typescript/src/App.ts | 13 +++++++++++++ 3 files changed, 29 insertions(+), 1 deletion(-) diff --git a/packages/babel-preset-react-app/create.js b/packages/babel-preset-react-app/create.js index 0f972477..a0423f25 100644 --- a/packages/babel-preset-react-app/create.js +++ b/packages/babel-preset-react-app/create.js @@ -113,8 +113,13 @@ module.exports = function(api, opts, env) { // Strip flow types before any other transform, emulating the behavior // order as-if the browser supported all of the succeeding features // https://github.com/facebook/create-react-app/pull/5182 - isFlowEnabled && + // We will conditionally enable this plugin below in overrides as it clashes with + // @babel/plugin-proposal-decorators when using TypeScript. + // https://github.com/facebook/create-react-app/issues/5741 + isFlowEnabled && [ require('@babel/plugin-transform-flow-strip-types').default, + false, + ], // Experimental macros support. Will be documented after it's had some time // in the wild. require('babel-plugin-macros'), @@ -177,6 +182,10 @@ module.exports = function(api, opts, env) { require('babel-plugin-dynamic-import-node'), ].filter(Boolean), overrides: [ + isFlowEnabled && { + exclude: /\.tsx?$/, + plugins: [require('@babel/plugin-transform-flow-strip-types').default], + }, isTypeScriptEnabled && { test: /\.tsx?$/, plugins: [ diff --git a/test/fixtures/typescript/src/App.test.ts b/test/fixtures/typescript/src/App.test.ts index cef45f28..fb0a9509 100644 --- a/test/fixtures/typescript/src/App.test.ts +++ b/test/fixtures/typescript/src/App.test.ts @@ -6,3 +6,9 @@ it('reads a typescript file with no syntax error', () => { expect(App.foo.baz!.n).toBe(123); expect(app.n).toBe(123); }); + +it('supports decorators', () => { + const app = new App(); + expect((app as any).annotated).toBe(true); + expect(app.decorated).toBe(42); +}); diff --git a/test/fixtures/typescript/src/App.ts b/test/fixtures/typescript/src/App.ts index f3c31414..da5cc719 100644 --- a/test/fixtures/typescript/src/App.ts +++ b/test/fixtures/typescript/src/App.ts @@ -10,10 +10,23 @@ type MyObject = Pick; class App { static foo: MyObject = { bar: true, baz: { n: 123 } }; n = App.foo.baz!.n; + @propertyDecorator + decorated; } function annotation(target: any) { target.annotated = true; } +function propertyDecorator(target: any, key: string) { + if (delete target[key]) { + Object.defineProperty(target, key, { + get() { + return 42; + }, + enumerable: true, + }); + } +} + export default App;