From c7f23ca8bfdd0d96ee7a38024b1f5589b0fa0fc4 Mon Sep 17 00:00:00 2001
From: Ethan Sharabi <ethans@wix.com>
Date: Tue, 19 Jun 2018 16:49:32 +0300
Subject: [PATCH] push dist to allow installing package from this fork

---
 .gitignore                                    |   1 -
 dist/cli.d.ts                                 |   1 +
 dist/cli.js                                   | 117 ++++++++++
 dist/cli.js.map                               |   1 +
 dist/compiler.d.ts                            |  19 ++
 dist/compiler.js                              | 135 +++++++++++
 dist/compiler.js.map                          |   1 +
 dist/helpers/build-prop-type-interface.d.ts   |  15 ++
 dist/helpers/build-prop-type-interface.js     | 166 ++++++++++++++
 dist/helpers/build-prop-type-interface.js.map |   1 +
 dist/helpers/index.d.ts                       |  83 +++++++
 dist/helpers/index.js                         | 182 +++++++++++++++
 dist/helpers/index.js.map                     |   1 +
 dist/index.d.ts                               |  18 ++
 dist/index.js                                 |  38 +++
 dist/index.js.map                             |   1 +
 ...pse-intersection-interfaces-transform.d.ts |  12 +
 ...lapse-intersection-interfaces-transform.js | 166 ++++++++++++++
 ...e-intersection-interfaces-transform.js.map |   1 +
 ...act-js-make-props-and-state-transform.d.ts |   8 +
 ...react-js-make-props-and-state-transform.js | 217 ++++++++++++++++++
 ...t-js-make-props-and-state-transform.js.map |   1 +
 ...ct-move-prop-types-to-class-transform.d.ts |  28 +++
 ...eact-move-prop-types-to-class-transform.js | 123 ++++++++++
 ...-move-prop-types-to-class-transform.js.map |   1 +
 ...emove-prop-types-assignment-transform.d.ts |  14 ++
 ...-remove-prop-types-assignment-transform.js |  26 +++
 ...ove-prop-types-assignment-transform.js.map |   1 +
 .../react-remove-prop-types-import.d.ts       |  15 ++
 .../react-remove-prop-types-import.js         |  52 +++++
 .../react-remove-prop-types-import.js.map     |   1 +
 ...ve-static-prop-types-member-transform.d.ts |  17 ++
 ...move-static-prop-types-member-transform.js |  48 ++++
 ...-static-prop-types-member-transform.js.map |   1 +
 ...ateless-function-make-props-transform.d.ts |  31 +++
 ...stateless-function-make-props-transform.js | 114 +++++++++
 ...eless-function-make-props-transform.js.map |   1 +
 package.json                                  |  10 +-
 38 files changed, 1665 insertions(+), 3 deletions(-)
 create mode 100644 dist/cli.d.ts
 create mode 100644 dist/cli.js
 create mode 100644 dist/cli.js.map
 create mode 100644 dist/compiler.d.ts
 create mode 100644 dist/compiler.js
 create mode 100644 dist/compiler.js.map
 create mode 100644 dist/helpers/build-prop-type-interface.d.ts
 create mode 100644 dist/helpers/build-prop-type-interface.js
 create mode 100644 dist/helpers/build-prop-type-interface.js.map
 create mode 100644 dist/helpers/index.d.ts
 create mode 100644 dist/helpers/index.js
 create mode 100644 dist/helpers/index.js.map
 create mode 100644 dist/index.d.ts
 create mode 100644 dist/index.js
 create mode 100644 dist/index.js.map
 create mode 100644 dist/transforms/collapse-intersection-interfaces-transform.d.ts
 create mode 100644 dist/transforms/collapse-intersection-interfaces-transform.js
 create mode 100644 dist/transforms/collapse-intersection-interfaces-transform.js.map
 create mode 100644 dist/transforms/react-js-make-props-and-state-transform.d.ts
 create mode 100644 dist/transforms/react-js-make-props-and-state-transform.js
 create mode 100644 dist/transforms/react-js-make-props-and-state-transform.js.map
 create mode 100644 dist/transforms/react-move-prop-types-to-class-transform.d.ts
 create mode 100644 dist/transforms/react-move-prop-types-to-class-transform.js
 create mode 100644 dist/transforms/react-move-prop-types-to-class-transform.js.map
 create mode 100644 dist/transforms/react-remove-prop-types-assignment-transform.d.ts
 create mode 100644 dist/transforms/react-remove-prop-types-assignment-transform.js
 create mode 100644 dist/transforms/react-remove-prop-types-assignment-transform.js.map
 create mode 100644 dist/transforms/react-remove-prop-types-import.d.ts
 create mode 100644 dist/transforms/react-remove-prop-types-import.js
 create mode 100644 dist/transforms/react-remove-prop-types-import.js.map
 create mode 100644 dist/transforms/react-remove-static-prop-types-member-transform.d.ts
 create mode 100644 dist/transforms/react-remove-static-prop-types-member-transform.js
 create mode 100644 dist/transforms/react-remove-static-prop-types-member-transform.js.map
 create mode 100644 dist/transforms/react-stateless-function-make-props-transform.d.ts
 create mode 100644 dist/transforms/react-stateless-function-make-props-transform.js
 create mode 100644 dist/transforms/react-stateless-function-make-props-transform.js.map

diff --git a/.gitignore b/.gitignore
index 6897440..ae1044b 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,5 +1,4 @@
 node_modules
-dist
 .DS_Store
 coverage/
 *.log
diff --git a/dist/cli.d.ts b/dist/cli.d.ts
new file mode 100644
index 0000000..cb0ff5c
--- /dev/null
+++ b/dist/cli.d.ts
@@ -0,0 +1 @@
+export {};
diff --git a/dist/cli.js b/dist/cli.js
new file mode 100644
index 0000000..23a363c
--- /dev/null
+++ b/dist/cli.js
@@ -0,0 +1,117 @@
+#!/usr/bin/env node
+"use strict";
+var __values = (this && this.__values) || function (o) {
+    var m = typeof Symbol === "function" && o[Symbol.iterator], i = 0;
+    if (m) return m.call(o);
+    return {
+        next: function () {
+            if (o && i >= o.length) o = void 0;
+            return { value: o && o[i++], done: !o };
+        }
+    };
+};
+Object.defineProperty(exports, "__esModule", { value: true });
+var program = require("commander");
+var glob = require("glob");
+var fs = require("fs");
+var path = require("path");
+var _1 = require(".");
+function resolveGlobs(globPatterns) {
+    var files = [];
+    function addFile(file) {
+        file = path.resolve(file);
+        if (files.indexOf(file) === -1) {
+            files.push(file);
+        }
+    }
+    globPatterns.forEach(function (pattern) {
+        if (/[{}*?+\[\]]/.test(pattern)) {
+            // Smells like globs
+            glob.sync(pattern, {}).forEach(function (file) {
+                addFile(file);
+            });
+        }
+        else {
+            addFile(pattern);
+        }
+    });
+    return files;
+}
+program
+    .version('1.0.0')
+    .option('--arrow-parens <avoid|always>', 'Include parentheses around a sole arrow function parameter.', 'avoid')
+    .option('--no-bracket-spacing', 'Do not print spaces between brackets.', false)
+    .option('--jsx-bracket-same-line', 'Put > on the last line instead of at a new line.', false)
+    .option('--print-width <int>', 'The line length where Prettier will try wrap.', 80)
+    .option('--prose-wrap <always|never|preserve> How to wrap prose. (markdown)', 'preserve')
+    .option('--no-semi', 'Do not print semicolons, except at the beginning of lines which may need them', false)
+    .option('--single-quote', 'Use single quotes instead of double quotes.', false)
+    .option('--tab-width <int>', 'Number of spaces per indentation level.', 2)
+    .option('--trailing-comma <none|es5|all>', 'Print trailing commas wherever possible when multi-line.', 'none')
+    .option('--use-tabs', 'Indent with tabs instead of spaces.', false)
+    .option('--ignore-prettier-errors', 'Ignore (but warn about) errors in Prettier', false)
+    .option('--keep-original-files', 'Keep original files', false)
+    .option('--keep-temporary-files', 'Keep temporary files', false)
+    .usage('[options] <filename or glob>')
+    .command('* [glob/filename...]')
+    .action(function (globPatterns) {
+    var prettierOptions = {
+        arrowParens: program.arrowParens,
+        bracketSpacing: !program.noBracketSpacing,
+        jsxBracketSameLine: !!program.jsxBracketSameLine,
+        printWidth: parseInt(program.printWidth, 10),
+        proseWrap: program.proseWrap,
+        semi: !program.noSemi,
+        singleQuote: !!program.singleQuote,
+        tabWidth: parseInt(program.tabWidth, 10),
+        trailingComma: program.trailingComma,
+        useTabs: !!program.useTabs,
+    };
+    var compilationOptions = {
+        ignorePrettierErrors: !!program.ignorePrettierErrors,
+    };
+    var files = resolveGlobs(globPatterns);
+    if (!files.length) {
+        throw new Error('Nothing to do. You must provide file names or glob patterns to transform.');
+    }
+    var errors = false;
+    try {
+        for (var files_1 = __values(files), files_1_1 = files_1.next(); !files_1_1.done; files_1_1 = files_1.next()) {
+            var filePath = files_1_1.value;
+            console.log("Transforming " + filePath + "...");
+            var newPath = filePath.replace(/\.jsx?$/, '.tsx');
+            var temporaryPath = filePath.replace(/\.jsx?$/, "_js2ts_" + +new Date() + ".tsx");
+            try {
+                fs.copyFileSync(filePath, temporaryPath);
+                var result = _1.run(temporaryPath, prettierOptions, compilationOptions);
+                fs.writeFileSync(newPath, result);
+                if (!program.keepOriginalFiles) {
+                    fs.unlinkSync(filePath);
+                }
+            }
+            catch (error) {
+                console.warn("Failed to convert " + filePath);
+                console.warn(error);
+                errors = true;
+            }
+            if (!program.keepTemporaryFiles) {
+                if (fs.existsSync(temporaryPath)) {
+                    fs.unlinkSync(temporaryPath);
+                }
+            }
+        }
+    }
+    catch (e_1_1) { e_1 = { error: e_1_1 }; }
+    finally {
+        try {
+            if (files_1_1 && !files_1_1.done && (_a = files_1.return)) _a.call(files_1);
+        }
+        finally { if (e_1) throw e_1.error; }
+    }
+    if (errors) {
+        process.exit(1);
+    }
+    var e_1, _a;
+});
+program.parse(process.argv);
+//# sourceMappingURL=cli.js.map
\ No newline at end of file
diff --git a/dist/cli.js.map b/dist/cli.js.map
new file mode 100644
index 0000000..24c4320
--- /dev/null
+++ b/dist/cli.js.map
@@ -0,0 +1 @@
+{"version":3,"file":"cli.js","sourceRoot":"/Users/ethans/Documents/workspace/src/","sources":["cli.ts"],"names":[],"mappings":"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"}
\ No newline at end of file
diff --git a/dist/compiler.d.ts b/dist/compiler.d.ts
new file mode 100644
index 0000000..8e80695
--- /dev/null
+++ b/dist/compiler.d.ts
@@ -0,0 +1,19 @@
+import * as prettier from 'prettier';
+import { TransformFactoryFactory } from '.';
+export interface CompilationOptions {
+    ignorePrettierErrors: boolean;
+}
+declare const DEFAULT_COMPILATION_OPTIONS: CompilationOptions;
+export { DEFAULT_COMPILATION_OPTIONS };
+/**
+ * Compile and return result TypeScript
+ * @param filePath Path to file to compile
+ */
+export declare function compile(filePath: string, factoryFactories: TransformFactoryFactory[], incomingPrettierOptions?: prettier.Options, compilationOptions?: CompilationOptions): string;
+/**
+ * Get Prettier options based on style of a JavaScript
+ * @param filePath Path to source file
+ * @param source Body of a JavaScript
+ * @param options Existing prettier option
+ */
+export declare function getPrettierOptions(filePath: string, source: string, options: prettier.Options): prettier.Options;
diff --git a/dist/compiler.js b/dist/compiler.js
new file mode 100644
index 0000000..7fc516b
--- /dev/null
+++ b/dist/compiler.js
@@ -0,0 +1,135 @@
+"use strict";
+var __values = (this && this.__values) || function (o) {
+    var m = typeof Symbol === "function" && o[Symbol.iterator], i = 0;
+    if (m) return m.call(o);
+    return {
+        next: function () {
+            if (o && i >= o.length) o = void 0;
+            return { value: o && o[i++], done: !o };
+        }
+    };
+};
+Object.defineProperty(exports, "__esModule", { value: true });
+var os = require("os");
+var fs = require("fs");
+var ts = require("typescript");
+var chalk_1 = require("chalk");
+var _ = require("lodash");
+var prettier = require("prettier");
+var detectIndent = require("detect-indent");
+var DEFAULT_COMPILATION_OPTIONS = {
+    ignorePrettierErrors: false,
+};
+exports.DEFAULT_COMPILATION_OPTIONS = DEFAULT_COMPILATION_OPTIONS;
+/**
+ * Compile and return result TypeScript
+ * @param filePath Path to file to compile
+ */
+function compile(filePath, factoryFactories, incomingPrettierOptions, compilationOptions) {
+    if (incomingPrettierOptions === void 0) { incomingPrettierOptions = {}; }
+    if (compilationOptions === void 0) { compilationOptions = DEFAULT_COMPILATION_OPTIONS; }
+    var compilerOptions = {
+        target: ts.ScriptTarget.ES2017,
+        module: ts.ModuleKind.ES2015,
+    };
+    var program = ts.createProgram([filePath], compilerOptions);
+    // `program.getSourceFiles()` will include those imported files,
+    // like: `import * as a from './file-a'`.
+    // We should only transform current file.
+    var sourceFiles = program.getSourceFiles().filter(function (sf) { return sf.fileName === filePath; });
+    var typeChecker = program.getTypeChecker();
+    var result = ts.transform(sourceFiles, factoryFactories.map(function (factoryFactory) { return factoryFactory(typeChecker); }, compilerOptions));
+    if (result.diagnostics && result.diagnostics.length) {
+        console.log(chalk_1.default.yellow("\n        ======================= Diagnostics for " + filePath + " =======================\n        "));
+        try {
+            for (var _a = __values(result.diagnostics), _b = _a.next(); !_b.done; _b = _a.next()) {
+                var diag = _b.value;
+                if (diag.file && diag.start) {
+                    var pos = diag.file.getLineAndCharacterOfPosition(diag.start);
+                    console.log("(" + pos.line + ", " + pos.character + ") " + diag.messageText);
+                }
+            }
+        }
+        catch (e_1_1) { e_1 = { error: e_1_1 }; }
+        finally {
+            try {
+                if (_b && !_b.done && (_c = _a.return)) _c.call(_a);
+            }
+            finally { if (e_1) throw e_1.error; }
+        }
+    }
+    var printer = ts.createPrinter();
+    // TODO: fix the index 0 access... What if program have multiple source files?
+    var printed = printer.printNode(ts.EmitHint.SourceFile, result.transformed[0], sourceFiles[0]);
+    var inputSource = fs.readFileSync(filePath, 'utf-8');
+    var prettierOptions = getPrettierOptions(filePath, inputSource, incomingPrettierOptions);
+    try {
+        return prettier.format(printed, prettierOptions);
+    }
+    catch (prettierError) {
+        if (compilationOptions.ignorePrettierErrors) {
+            console.warn("Prettier failed for " + filePath + " (ignorePrettierErrors is on):");
+            console.warn(prettierError);
+            return printed;
+        }
+        throw prettierError;
+    }
+    var e_1, _c;
+}
+exports.compile = compile;
+/**
+ * Get Prettier options based on style of a JavaScript
+ * @param filePath Path to source file
+ * @param source Body of a JavaScript
+ * @param options Existing prettier option
+ */
+function getPrettierOptions(filePath, source, options) {
+    var resolvedOptions = prettier.resolveConfig.sync(filePath);
+    if (resolvedOptions) {
+        _.defaults(resolvedOptions, options);
+        return resolvedOptions;
+    }
+    var _a = detectIndent(source), indentAmount = _a.amount, indentType = _a.type;
+    var sourceWidth = getCodeWidth(source, 80);
+    var semi = getUseOfSemi(source);
+    var quotations = getQuotation(source);
+    _.defaults(Object.assign({}, options), {
+        tabWidth: indentAmount,
+        useTabs: indentType && indentType === 'tab',
+        printWidth: sourceWidth,
+        semi: semi,
+        singleQuote: quotations === 'single',
+    });
+    return options;
+}
+exports.getPrettierOptions = getPrettierOptions;
+/**
+ * Given body of a source file, return its code width
+ * @param source
+ */
+function getCodeWidth(source, defaultWidth) {
+    return source.split(os.EOL).reduce(function (result, line) { return Math.max(result, line.length); }, defaultWidth);
+}
+/**
+ * Detect if a source file is using semicolon
+ * @todo: use an actual parser. This is not a proper implementation
+ * @param source
+ * @return true if code is using semicolons
+ */
+function getUseOfSemi(source) {
+    return source.indexOf(';') !== -1;
+}
+/**
+ * Detect if a source file is using single quotes or double quotes
+ * @todo use an actual parser. This is not a proper implementation
+ * @param source
+ */
+function getQuotation(source) {
+    var numberOfSingleQuotes = (source.match(/\'/g) || []).length;
+    var numberOfDoubleQuotes = (source.match(/\"/g) || []).length;
+    if (numberOfSingleQuotes > numberOfDoubleQuotes) {
+        return 'single';
+    }
+    return 'double';
+}
+//# sourceMappingURL=compiler.js.map
\ No newline at end of file
diff --git a/dist/compiler.js.map b/dist/compiler.js.map
new file mode 100644
index 0000000..bc3ed5b
--- /dev/null
+++ b/dist/compiler.js.map
@@ -0,0 +1 @@
+{"version":3,"file":"compiler.js","sourceRoot":"/Users/ethans/Documents/workspace/src/","sources":["compiler.ts"],"names":[],"mappings":"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"}
\ No newline at end of file
diff --git a/dist/helpers/build-prop-type-interface.d.ts b/dist/helpers/build-prop-type-interface.d.ts
new file mode 100644
index 0000000..327cdc2
--- /dev/null
+++ b/dist/helpers/build-prop-type-interface.d.ts
@@ -0,0 +1,15 @@
+import * as ts from 'typescript';
+/**
+ * Build props interface from propTypes object
+ * @example
+ * {
+ *   foo: React.PropTypes.string.isRequired
+ * }
+ *
+ * becomes
+ * {
+ *  foo: string;
+ * }
+ * @param objectLiteral
+ */
+export declare function buildInterfaceFromPropTypeObjectLiteral(objectLiteral: ts.ObjectLiteralExpression): ts.TypeLiteralNode;
diff --git a/dist/helpers/build-prop-type-interface.js b/dist/helpers/build-prop-type-interface.js
new file mode 100644
index 0000000..489682f
--- /dev/null
+++ b/dist/helpers/build-prop-type-interface.js
@@ -0,0 +1,166 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+var ts = require("typescript");
+/**
+ * Build props interface from propTypes object
+ * @example
+ * {
+ *   foo: React.PropTypes.string.isRequired
+ * }
+ *
+ * becomes
+ * {
+ *  foo: string;
+ * }
+ * @param objectLiteral
+ */
+function buildInterfaceFromPropTypeObjectLiteral(objectLiteral) {
+    var members = objectLiteral.properties
+        // We only need to process PropertyAssignment:
+        // {
+        //    a: 123     // PropertyAssignment
+        // }
+        //
+        // filter out:
+        // {
+        //   a() {},     // MethodDeclaration
+        //   b,          // ShorthandPropertyAssignment
+        //   ...c,       // SpreadAssignment
+        //   get d() {}, // AccessorDeclaration
+        // }
+        .filter(ts.isPropertyAssignment)
+        // Ignore children, React types have it
+        .filter(function (property) { return property.name.getText() !== 'children'; })
+        .map(function (propertyAssignment) {
+        var name = propertyAssignment.name.getText();
+        var initializer = propertyAssignment.initializer;
+        var isRequired = isPropTypeRequired(initializer);
+        var typeExpression = isRequired
+            ? // We have guaranteed the type in `isPropTypeRequired()`
+                initializer.expression
+            : initializer;
+        var typeValue = getTypeFromReactPropTypeExpression(typeExpression);
+        return ts.createPropertySignature([], name, isRequired ? undefined : ts.createToken(ts.SyntaxKind.QuestionToken), typeValue, undefined);
+    });
+    return ts.createTypeLiteralNode(members);
+}
+exports.buildInterfaceFromPropTypeObjectLiteral = buildInterfaceFromPropTypeObjectLiteral;
+/**
+ * Turns React.PropTypes.* into TypeScript type value
+ *
+ * @param node React propTypes value
+ */
+function getTypeFromReactPropTypeExpression(node) {
+    var result = null;
+    if (ts.isPropertyAccessExpression(node)) {
+        /**
+         * PropTypes.array,
+         * PropTypes.bool,
+         * PropTypes.func,
+         * PropTypes.number,
+         * PropTypes.object,
+         * PropTypes.string,
+         * PropTypes.symbol, (ignore)
+         * PropTypes.node,
+         * PropTypes.element,
+         * PropTypes.any,
+         */
+        var text = node.getText().replace(/React\.PropTypes\./, '');
+        if (/string/.test(text)) {
+            result = ts.createKeywordTypeNode(ts.SyntaxKind.StringKeyword);
+        }
+        else if (/any/.test(text)) {
+            result = ts.createKeywordTypeNode(ts.SyntaxKind.AnyKeyword);
+        }
+        else if (/array/.test(text)) {
+            result = ts.createArrayTypeNode(ts.createKeywordTypeNode(ts.SyntaxKind.AnyKeyword));
+        }
+        else if (/bool/.test(text)) {
+            result = ts.createKeywordTypeNode(ts.SyntaxKind.BooleanKeyword);
+        }
+        else if (/number/.test(text)) {
+            result = ts.createKeywordTypeNode(ts.SyntaxKind.NumberKeyword);
+        }
+        else if (/object/.test(text)) {
+            result = ts.createKeywordTypeNode(ts.SyntaxKind.ObjectKeyword);
+        }
+        else if (/node/.test(text)) {
+            result = ts.createTypeReferenceNode('React.ReactNode', []);
+        }
+        else if (/element/.test(text)) {
+            result = ts.createTypeReferenceNode('JSX.Element', []);
+        }
+        else if (/func/.test(text)) {
+            var arrayOfAny = ts.createParameter([], [], ts.createToken(ts.SyntaxKind.DotDotDotToken), 'args', undefined, ts.createArrayTypeNode(ts.createKeywordTypeNode(ts.SyntaxKind.AnyKeyword)), undefined);
+            result = ts.createFunctionTypeNode([], [arrayOfAny], ts.createKeywordTypeNode(ts.SyntaxKind.AnyKeyword));
+        }
+    }
+    else if (ts.isCallExpression(node)) {
+        /**
+         * PropTypes.instanceOf(), (ignore)
+         * PropTypes.oneOf(), // only support oneOf([1, 2]), oneOf(['a', 'b'])
+         * PropTypes.oneOfType(),
+         * PropTypes.arrayOf(),
+         * PropTypes.objectOf(),
+         * PropTypes.shape(),
+         */
+        var text = node.expression.getText();
+        if (/oneOf$/.test(text)) {
+            var argument = node.arguments[0];
+            if (ts.isArrayLiteralExpression(argument)) {
+                if (argument.elements.every(function (elm) { return ts.isStringLiteral(elm) || ts.isNumericLiteral(elm); })) {
+                    result = ts.createUnionTypeNode(argument.elements.map(function (elm) {
+                        return ts.createLiteralTypeNode(elm);
+                    }));
+                }
+            }
+        }
+        else if (/oneOfType$/.test(text)) {
+            var argument = node.arguments[0];
+            if (ts.isArrayLiteralExpression(argument)) {
+                result = ts.createUnionOrIntersectionTypeNode(ts.SyntaxKind.UnionType, argument.elements.map(function (elm) { return getTypeFromReactPropTypeExpression(elm); }));
+            }
+        }
+        else if (/arrayOf$/.test(text)) {
+            var argument = node.arguments[0];
+            if (argument) {
+                result = ts.createArrayTypeNode(getTypeFromReactPropTypeExpression(argument));
+            }
+        }
+        else if (/objectOf$/.test(text)) {
+            var argument = node.arguments[0];
+            if (argument) {
+                result = ts.createTypeLiteralNode([
+                    ts.createIndexSignature(undefined, undefined, [
+                        ts.createParameter(undefined, undefined, undefined, 'key', undefined, ts.createKeywordTypeNode(ts.SyntaxKind.StringKeyword)),
+                    ], getTypeFromReactPropTypeExpression(argument)),
+                ]);
+            }
+        }
+        else if (/shape$/.test(text)) {
+            var argument = node.arguments[0];
+            if (ts.isObjectLiteralExpression(argument)) {
+                return buildInterfaceFromPropTypeObjectLiteral(argument);
+            }
+        }
+    }
+    /**
+     * customProp,
+     * anything others
+     */
+    if (result === null) {
+        result = ts.createKeywordTypeNode(ts.SyntaxKind.AnyKeyword);
+    }
+    return result;
+}
+/**
+ * Decide if node is required
+ * @param node React propTypes member node
+ */
+function isPropTypeRequired(node) {
+    if (!ts.isPropertyAccessExpression(node))
+        return false;
+    var text = node.getText().replace(/React\.PropTypes\./, '');
+    return /\.isRequired/.test(text);
+}
+//# sourceMappingURL=build-prop-type-interface.js.map
\ No newline at end of file
diff --git a/dist/helpers/build-prop-type-interface.js.map b/dist/helpers/build-prop-type-interface.js.map
new file mode 100644
index 0000000..3744e0b
--- /dev/null
+++ b/dist/helpers/build-prop-type-interface.js.map
@@ -0,0 +1 @@
+{"version":3,"file":"build-prop-type-interface.js","sourceRoot":"/Users/ethans/Documents/workspace/src/","sources":["helpers/build-prop-type-interface.ts"],"names":[],"mappings":"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"}
\ No newline at end of file
diff --git a/dist/helpers/index.d.ts b/dist/helpers/index.d.ts
new file mode 100644
index 0000000..45d35d5
--- /dev/null
+++ b/dist/helpers/index.d.ts
@@ -0,0 +1,83 @@
+import * as ts from 'typescript';
+export * from './build-prop-type-interface';
+/**
+ * If a class declaration a react class?
+ * @param classDeclaration
+ * @param typeChecker
+ */
+export declare function isReactComponent(classDeclaration: ts.ClassDeclaration, typeChecker: ts.TypeChecker): boolean;
+/**
+ * Determine if a ts.HeritageClause is React HeritageClause
+ *
+ * @example `extends React.Component<{}, {}>` is a React HeritageClause
+ *
+ * @todo: this is lazy. Use the typeChecker instead
+ * @param clause
+ */
+export declare function isReactHeritageClause(clause: ts.HeritageClause): boolean;
+/**
+ * Return true if a statement is a React propType assignment statement
+ * @example
+ * SomeComponent.propTypes = { foo: React.PropTypes.string };
+ * @param statement
+ */
+export declare function isReactPropTypeAssignmentStatement(statement: ts.Statement): statement is ts.ExpressionStatement;
+/**
+ * Does class member have a "static" member?
+ * @param classMember
+ */
+export declare function hasStaticModifier(classMember: ts.ClassElement): boolean;
+/**
+ * Is class member a React "propTypes" member?
+ * @param classMember
+ * @param sourceFile
+ */
+export declare function isPropTypesMember(classMember: ts.ClassElement, sourceFile: ts.SourceFile): boolean;
+/**
+ * Get component name off of a propType assignment statement
+ * @param propTypeAssignment
+ * @param sourceFile
+ */
+export declare function getComponentName(propTypeAssignment: ts.Statement, sourceFile: ts.SourceFile): string;
+/**
+ * Convert react stateless function to arrow function
+ * @example
+ * Before:
+ * function Hello(message) {
+ *   return <div>{message}</div>
+ * }
+ *
+ * After:
+ * const Hello = message => {
+ *   return <div>{message}</div>
+ * }
+ */
+export declare function convertReactStatelessFunctionToArrowFunction(statelessFunc: ts.FunctionDeclaration | ts.VariableStatement): ts.VariableStatement;
+/**
+ * Insert an item in middle of an array after a specific item
+ * @param collection
+ * @param afterItem
+ * @param newItem
+ */
+export declare function insertAfter<T>(collection: ArrayLike<T>, afterItem: T, newItem: T): T[];
+/**
+ * Insert an item in middle of an array before a specific item
+ * @param collection
+ * @param beforeItem
+ * @param newItem
+ */
+export declare function insertBefore<T>(collection: ArrayLike<T>, beforeItem: T, newItems: T | T[]): T[];
+/**
+ * Replace an item in a collection with another item
+ * @param collection
+ * @param item
+ * @param newItem
+ */
+export declare function replaceItem<T>(collection: ArrayLike<T>, item: T, newItem: T): T[];
+/**
+ * Remove an item from a collection
+ * @param collection
+ * @param item
+ * @param newItem
+ */
+export declare function removeItem<T>(collection: ArrayLike<T>, item: T): T[];
diff --git a/dist/helpers/index.js b/dist/helpers/index.js
new file mode 100644
index 0000000..df30b66
--- /dev/null
+++ b/dist/helpers/index.js
@@ -0,0 +1,182 @@
+"use strict";
+function __export(m) {
+    for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];
+}
+Object.defineProperty(exports, "__esModule", { value: true });
+var ts = require("typescript");
+var _ = require("lodash");
+__export(require("./build-prop-type-interface"));
+/**
+ * If a class declaration a react class?
+ * @param classDeclaration
+ * @param typeChecker
+ */
+function isReactComponent(classDeclaration, typeChecker) {
+    // Only classes that extend React.Component
+    if (!classDeclaration.heritageClauses) {
+        return false;
+    }
+    if (classDeclaration.heritageClauses.length !== 1) {
+        return false;
+    }
+    var firstHeritageClauses = classDeclaration.heritageClauses[0];
+    if (firstHeritageClauses.token !== ts.SyntaxKind.ExtendsKeyword) {
+        return false;
+    }
+    var expressionWithTypeArguments = firstHeritageClauses.types[0];
+    if (!expressionWithTypeArguments) {
+        return false;
+    }
+    // Try type checker and fallback to node text
+    var type = typeChecker.getTypeAtLocation(expressionWithTypeArguments);
+    var typeSymbol = type && type.symbol && type.symbol.name;
+    if (!typeSymbol) {
+        typeSymbol = expressionWithTypeArguments.expression.getText();
+    }
+    if (!/React\.Component|Component/.test(typeSymbol)) {
+        return false;
+    }
+    return true;
+}
+exports.isReactComponent = isReactComponent;
+/**
+ * Determine if a ts.HeritageClause is React HeritageClause
+ *
+ * @example `extends React.Component<{}, {}>` is a React HeritageClause
+ *
+ * @todo: this is lazy. Use the typeChecker instead
+ * @param clause
+ */
+function isReactHeritageClause(clause) {
+    return (clause.token === ts.SyntaxKind.ExtendsKeyword &&
+        clause.types.length === 1 &&
+        ts.isExpressionWithTypeArguments(clause.types[0]) &&
+        /Component/.test(clause.types[0].expression.getText()));
+}
+exports.isReactHeritageClause = isReactHeritageClause;
+/**
+ * Return true if a statement is a React propType assignment statement
+ * @example
+ * SomeComponent.propTypes = { foo: React.PropTypes.string };
+ * @param statement
+ */
+function isReactPropTypeAssignmentStatement(statement) {
+    return (ts.isExpressionStatement(statement) &&
+        ts.isBinaryExpression(statement.expression) &&
+        statement.expression.operatorToken.kind === ts.SyntaxKind.FirstAssignment &&
+        ts.isPropertyAccessExpression(statement.expression.left) &&
+        /\.propTypes$|\.propTypes\..+$/.test(statement.expression.left.getText()));
+}
+exports.isReactPropTypeAssignmentStatement = isReactPropTypeAssignmentStatement;
+/**
+ * Does class member have a "static" member?
+ * @param classMember
+ */
+function hasStaticModifier(classMember) {
+    if (!classMember.modifiers) {
+        return false;
+    }
+    var staticModifier = _.find(classMember.modifiers, function (modifier) {
+        return modifier.kind == ts.SyntaxKind.StaticKeyword;
+    });
+    return staticModifier !== undefined;
+}
+exports.hasStaticModifier = hasStaticModifier;
+/**
+ * Is class member a React "propTypes" member?
+ * @param classMember
+ * @param sourceFile
+ */
+function isPropTypesMember(classMember, sourceFile) {
+    try {
+        var name_1 = classMember.name !== undefined && ts.isIdentifier(classMember.name) ? classMember.name.escapedText : null;
+        return name_1 === 'propTypes';
+    }
+    catch (e) {
+        return false;
+    }
+}
+exports.isPropTypesMember = isPropTypesMember;
+/**
+ * Get component name off of a propType assignment statement
+ * @param propTypeAssignment
+ * @param sourceFile
+ */
+function getComponentName(propTypeAssignment, sourceFile) {
+    var text = propTypeAssignment.getText(sourceFile);
+    return text.substr(0, text.indexOf('.'));
+}
+exports.getComponentName = getComponentName;
+/**
+ * Convert react stateless function to arrow function
+ * @example
+ * Before:
+ * function Hello(message) {
+ *   return <div>{message}</div>
+ * }
+ *
+ * After:
+ * const Hello = message => {
+ *   return <div>{message}</div>
+ * }
+ */
+function convertReactStatelessFunctionToArrowFunction(statelessFunc) {
+    if (ts.isVariableStatement(statelessFunc))
+        return statelessFunc;
+    var funcName = statelessFunc.name || 'Component';
+    var funcBody = statelessFunc.body || ts.createBlock([]);
+    var initializer = ts.createArrowFunction(undefined, undefined, statelessFunc.parameters, undefined, undefined, funcBody);
+    return ts.createVariableStatement(statelessFunc.modifiers, ts.createVariableDeclarationList([ts.createVariableDeclaration(funcName, undefined, initializer)], ts.NodeFlags.Const));
+}
+exports.convertReactStatelessFunctionToArrowFunction = convertReactStatelessFunctionToArrowFunction;
+/**
+ * Insert an item in middle of an array after a specific item
+ * @param collection
+ * @param afterItem
+ * @param newItem
+ */
+function insertAfter(collection, afterItem, newItem) {
+    var index = _.indexOf(collection, afterItem) + 1;
+    return _.slice(collection, 0, index)
+        .concat(newItem)
+        .concat(_.slice(collection, index));
+}
+exports.insertAfter = insertAfter;
+/**
+ * Insert an item in middle of an array before a specific item
+ * @param collection
+ * @param beforeItem
+ * @param newItem
+ */
+function insertBefore(collection, beforeItem, newItems) {
+    var index = _.indexOf(collection, beforeItem);
+    return _.slice(collection, 0, index)
+        .concat(newItems)
+        .concat(_.slice(collection, index));
+}
+exports.insertBefore = insertBefore;
+/**
+ * Replace an item in a collection with another item
+ * @param collection
+ * @param item
+ * @param newItem
+ */
+function replaceItem(collection, item, newItem) {
+    var index = _.indexOf(collection, item);
+    return _.slice(collection, 0, index)
+        .concat(newItem)
+        .concat(_.slice(collection, index + 1));
+}
+exports.replaceItem = replaceItem;
+/**
+ * Remove an item from a collection
+ * @param collection
+ * @param item
+ * @param newItem
+ */
+function removeItem(collection, item) {
+    var index = _.indexOf(collection, item);
+    return _.slice(collection, 0, index).concat(_.slice(collection, index + 1));
+}
+exports.removeItem = removeItem;
+//# sourceMappingURL=index.js.map
\ No newline at end of file
diff --git a/dist/helpers/index.js.map b/dist/helpers/index.js.map
new file mode 100644
index 0000000..09f21d8
--- /dev/null
+++ b/dist/helpers/index.js.map
@@ -0,0 +1 @@
+{"version":3,"file":"index.js","sourceRoot":"/Users/ethans/Documents/workspace/src/","sources":["helpers/index.ts"],"names":[],"mappings":"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"}
\ No newline at end of file
diff --git a/dist/index.d.ts b/dist/index.d.ts
new file mode 100644
index 0000000..4b8d2a1
--- /dev/null
+++ b/dist/index.d.ts
@@ -0,0 +1,18 @@
+import * as ts from 'typescript';
+import * as prettier from 'prettier';
+import { compile, CompilationOptions } from './compiler';
+import { reactJSMakePropsAndStateInterfaceTransformFactoryFactory } from './transforms/react-js-make-props-and-state-transform';
+import { reactRemovePropTypesAssignmentTransformFactoryFactory } from './transforms/react-remove-prop-types-assignment-transform';
+import { reactMovePropTypesToClassTransformFactoryFactory } from './transforms/react-move-prop-types-to-class-transform';
+import { collapseIntersectionInterfacesTransformFactoryFactory } from './transforms/collapse-intersection-interfaces-transform';
+import { reactRemoveStaticPropTypesMemberTransformFactoryFactory } from './transforms/react-remove-static-prop-types-member-transform';
+import { reactStatelessFunctionMakePropsTransformFactoryFactory } from './transforms/react-stateless-function-make-props-transform';
+import { reactRemovePropTypesImportTransformFactoryFactory } from './transforms/react-remove-prop-types-import';
+export { reactMovePropTypesToClassTransformFactoryFactory, reactJSMakePropsAndStateInterfaceTransformFactoryFactory, reactStatelessFunctionMakePropsTransformFactoryFactory, collapseIntersectionInterfacesTransformFactoryFactory, reactRemovePropTypesAssignmentTransformFactoryFactory, reactRemoveStaticPropTypesMemberTransformFactoryFactory, reactRemovePropTypesImportTransformFactoryFactory, compile };
+export declare const allTransforms: (typeof reactMovePropTypesToClassTransformFactoryFactory)[];
+export declare type TransformFactoryFactory = (typeChecker: ts.TypeChecker) => ts.TransformerFactory<ts.SourceFile>;
+/**
+ * Run React JavaScript to TypeScript transform for file at `filePath`
+ * @param filePath
+ */
+export declare function run(filePath: string, prettierOptions?: prettier.Options, compilationOptions?: CompilationOptions): string;
diff --git a/dist/index.js b/dist/index.js
new file mode 100644
index 0000000..3767321
--- /dev/null
+++ b/dist/index.js
@@ -0,0 +1,38 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+var compiler_1 = require("./compiler");
+exports.compile = compiler_1.compile;
+var react_js_make_props_and_state_transform_1 = require("./transforms/react-js-make-props-and-state-transform");
+exports.reactJSMakePropsAndStateInterfaceTransformFactoryFactory = react_js_make_props_and_state_transform_1.reactJSMakePropsAndStateInterfaceTransformFactoryFactory;
+var react_remove_prop_types_assignment_transform_1 = require("./transforms/react-remove-prop-types-assignment-transform");
+exports.reactRemovePropTypesAssignmentTransformFactoryFactory = react_remove_prop_types_assignment_transform_1.reactRemovePropTypesAssignmentTransformFactoryFactory;
+var react_move_prop_types_to_class_transform_1 = require("./transforms/react-move-prop-types-to-class-transform");
+exports.reactMovePropTypesToClassTransformFactoryFactory = react_move_prop_types_to_class_transform_1.reactMovePropTypesToClassTransformFactoryFactory;
+var collapse_intersection_interfaces_transform_1 = require("./transforms/collapse-intersection-interfaces-transform");
+exports.collapseIntersectionInterfacesTransformFactoryFactory = collapse_intersection_interfaces_transform_1.collapseIntersectionInterfacesTransformFactoryFactory;
+var react_remove_static_prop_types_member_transform_1 = require("./transforms/react-remove-static-prop-types-member-transform");
+exports.reactRemoveStaticPropTypesMemberTransformFactoryFactory = react_remove_static_prop_types_member_transform_1.reactRemoveStaticPropTypesMemberTransformFactoryFactory;
+var react_stateless_function_make_props_transform_1 = require("./transforms/react-stateless-function-make-props-transform");
+exports.reactStatelessFunctionMakePropsTransformFactoryFactory = react_stateless_function_make_props_transform_1.reactStatelessFunctionMakePropsTransformFactoryFactory;
+var react_remove_prop_types_import_1 = require("./transforms/react-remove-prop-types-import");
+exports.reactRemovePropTypesImportTransformFactoryFactory = react_remove_prop_types_import_1.reactRemovePropTypesImportTransformFactoryFactory;
+exports.allTransforms = [
+    react_move_prop_types_to_class_transform_1.reactMovePropTypesToClassTransformFactoryFactory,
+    react_js_make_props_and_state_transform_1.reactJSMakePropsAndStateInterfaceTransformFactoryFactory,
+    react_stateless_function_make_props_transform_1.reactStatelessFunctionMakePropsTransformFactoryFactory,
+    collapse_intersection_interfaces_transform_1.collapseIntersectionInterfacesTransformFactoryFactory,
+    react_remove_prop_types_assignment_transform_1.reactRemovePropTypesAssignmentTransformFactoryFactory,
+    react_remove_static_prop_types_member_transform_1.reactRemoveStaticPropTypesMemberTransformFactoryFactory,
+    react_remove_prop_types_import_1.reactRemovePropTypesImportTransformFactoryFactory,
+];
+/**
+ * Run React JavaScript to TypeScript transform for file at `filePath`
+ * @param filePath
+ */
+function run(filePath, prettierOptions, compilationOptions) {
+    if (prettierOptions === void 0) { prettierOptions = {}; }
+    if (compilationOptions === void 0) { compilationOptions = compiler_1.DEFAULT_COMPILATION_OPTIONS; }
+    return compiler_1.compile(filePath, exports.allTransforms, prettierOptions, compilationOptions);
+}
+exports.run = run;
+//# sourceMappingURL=index.js.map
\ No newline at end of file
diff --git a/dist/index.js.map b/dist/index.js.map
new file mode 100644
index 0000000..ce25f71
--- /dev/null
+++ b/dist/index.js.map
@@ -0,0 +1 @@
+{"version":3,"file":"index.js","sourceRoot":"/Users/ethans/Documents/workspace/src/","sources":["index.ts"],"names":[],"mappings":";;AAGA,uCAAsF;AAiBlF,kBAjBK,kBAAO,CAiBL;AAhBX,gHAAgI;AAU5H,mEAVK,kGAAwD,CAUL;AAT5D,0HAAkI;AAY9H,gEAZK,oGAAqD,CAYL;AAXzD,kHAAyH;AAOrH,2DAPK,2FAAgD,CAOL;AANpD,sHAAgI;AAS5H,gEATK,kGAAqD,CASL;AARzD,gIAAuI;AAUnI,kEAVK,yGAAuD,CAUL;AAT3D,4HAAoI;AAMhI,iEANK,sGAAsD,CAML;AAL1D,8FAAgH;AAS5G,4DATK,kFAAiD,CASL;AAIxC,QAAA,aAAa,GAAG;IACzB,2FAAgD;IAChD,kGAAwD;IACxD,sGAAsD;IACtD,kGAAqD;IACrD,oGAAqD;IACrD,yGAAuD;IACvD,kFAAiD;CACpD,CAAC;AAIF;;;GAGG;AACH,aACI,QAAgB,EAChB,eAAsC,EACtC,kBAAoE;IADpE,gCAAA,EAAA,oBAAsC;IACtC,mCAAA,EAAA,qBAAyC,sCAA2B;IAEpE,OAAO,kBAAO,CAAC,QAAQ,EAAE,qBAAa,EAAE,eAAe,EAAE,kBAAkB,CAAC,CAAC;AACjF,CAAC;AAND,kBAMC"}
\ No newline at end of file
diff --git a/dist/transforms/collapse-intersection-interfaces-transform.d.ts b/dist/transforms/collapse-intersection-interfaces-transform.d.ts
new file mode 100644
index 0000000..09a87cf
--- /dev/null
+++ b/dist/transforms/collapse-intersection-interfaces-transform.d.ts
@@ -0,0 +1,12 @@
+import * as ts from 'typescript';
+/**
+ * Collapse unnecessary intersections between type literals
+ *
+ * @example
+ * Before:
+ * type Foo = {foo: string;} & {bar: number;}
+ *
+ * After
+ * type Foo = {foo: string; bar: number;}
+ */
+export declare function collapseIntersectionInterfacesTransformFactoryFactory(typeChecker: ts.TypeChecker): ts.TransformerFactory<ts.SourceFile>;
diff --git a/dist/transforms/collapse-intersection-interfaces-transform.js b/dist/transforms/collapse-intersection-interfaces-transform.js
new file mode 100644
index 0000000..3792643
--- /dev/null
+++ b/dist/transforms/collapse-intersection-interfaces-transform.js
@@ -0,0 +1,166 @@
+"use strict";
+var __values = (this && this.__values) || function (o) {
+    var m = typeof Symbol === "function" && o[Symbol.iterator], i = 0;
+    if (m) return m.call(o);
+    return {
+        next: function () {
+            if (o && i >= o.length) o = void 0;
+            return { value: o && o[i++], done: !o };
+        }
+    };
+};
+var __read = (this && this.__read) || function (o, n) {
+    var m = typeof Symbol === "function" && o[Symbol.iterator];
+    if (!m) return o;
+    var i = m.call(o), r, ar = [], e;
+    try {
+        while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
+    }
+    catch (error) { e = { error: error }; }
+    finally {
+        try {
+            if (r && !r.done && (m = i["return"])) m.call(i);
+        }
+        finally { if (e) throw e.error; }
+    }
+    return ar;
+};
+Object.defineProperty(exports, "__esModule", { value: true });
+var ts = require("typescript");
+var _ = require("lodash");
+/**
+ * Collapse unnecessary intersections between type literals
+ *
+ * @example
+ * Before:
+ * type Foo = {foo: string;} & {bar: number;}
+ *
+ * After
+ * type Foo = {foo: string; bar: number;}
+ */
+function collapseIntersectionInterfacesTransformFactoryFactory(typeChecker) {
+    return function collapseIntersectionInterfacesTransformFactory(context) {
+        return function collapseIntersectionInterfacesTransform(sourceFile) {
+            var visited = ts.visitEachChild(sourceFile, visitor, context);
+            ts.addEmitHelpers(visited, context.readEmitHelpers());
+            return visited;
+            function visitor(node) {
+                if (ts.isTypeAliasDeclaration(node)) {
+                    return visitTypeAliasDeclaration(node);
+                }
+                return node;
+            }
+            function visitTypeAliasDeclaration(node) {
+                if (ts.isIntersectionTypeNode(node.type)) {
+                    return ts.createTypeAliasDeclaration([], [], node.name.text, [], visitIntersectionTypeNode(node.type));
+                }
+                return node;
+            }
+            function visitIntersectionTypeNode(node) {
+                // Only intersection of type literals can be colapsed.
+                // We are currently ignoring intersections such as `{foo: string} & {bar: string} & TypeRef`
+                // TODO: handle mix of type references and multiple literal types
+                if (!node.types.every(function (typeNode) { return ts.isTypeLiteralNode(typeNode); })) {
+                    return node;
+                }
+                // We need cast `node.type.types` to `ts.NodeArray<ts.TypeLiteralNode>`
+                // because TypeScript can't figure out `node.type.types.every(ts.isTypeLiteralNode)`
+                var types = node.types;
+                // Build a map of member names to all of types found in intersectioning type literals
+                // For instance {foo: string, bar: number} & { foo: number } will result in a map like this:
+                // Map {
+                //   'foo' => Set { 'string', 'number' },
+                //   'bar' => Set { 'number' }
+                // }
+                var membersMap = new Map();
+                // A sepecial member of type literal nodes is index signitures which don't have a name
+                // We use this symbol to track it in our members map
+                var INDEX_SIGNITUTRE_MEMBER = Symbol('Index signiture member');
+                // Keep a reference of first index signiture member parameters. (ignore rest)
+                var indexMemberParameter = null;
+                // Iterate through all of type literal nodes members and add them to the members map
+                types.forEach(function (typeNode) {
+                    typeNode.members.forEach(function (member) {
+                        if (ts.isIndexSignatureDeclaration(member)) {
+                            if (member.type !== undefined) {
+                                if (membersMap.has(INDEX_SIGNITUTRE_MEMBER)) {
+                                    membersMap.get(INDEX_SIGNITUTRE_MEMBER).add(member.type);
+                                }
+                                else {
+                                    indexMemberParameter = member.parameters;
+                                    membersMap.set(INDEX_SIGNITUTRE_MEMBER, new Set([member.type]));
+                                }
+                            }
+                        }
+                        else if (ts.isPropertySignature(member)) {
+                            if (member.type !== undefined) {
+                                var memberName = member.name.getText(sourceFile);
+                                // For unknown reasons, member.name.getText() is returning nothing in some cases
+                                // This is probably because previous transformers did something with the AST that
+                                // index of text string of member identifier is lost
+                                // TODO: investigate
+                                if (!memberName) {
+                                    memberName = member.name.escapedText;
+                                }
+                                if (membersMap.has(memberName)) {
+                                    membersMap.get(memberName).add(member.type);
+                                }
+                                else {
+                                    membersMap.set(memberName, new Set([member.type]));
+                                }
+                            }
+                        }
+                    });
+                });
+                // Result type literal members list
+                var finalMembers = [];
+                try {
+                    // Put together the map into a type literal that has member per each map entery and type of that
+                    // member is a union of all types in vlues for that member name in members map
+                    // if a member has only one type, create a simple type literal for it
+                    for (var _a = __values(membersMap.entries()), _b = _a.next(); !_b.done; _b = _a.next()) {
+                        var _c = __read(_b.value, 2), name_1 = _c[0], types_1 = _c[1];
+                        if (typeof name_1 === 'symbol') {
+                            continue;
+                        }
+                        // if for this name there is only one type found use the first type, otherwise make a union of all types
+                        var resultType = types_1.size === 1 ? Array.from(types_1)[0] : createUnionType(Array.from(types_1));
+                        finalMembers.push(ts.createPropertySignature([], name_1, undefined, resultType, undefined));
+                    }
+                }
+                catch (e_1_1) { e_1 = { error: e_1_1 }; }
+                finally {
+                    try {
+                        if (_b && !_b.done && (_d = _a.return)) _d.call(_a);
+                    }
+                    finally { if (e_1) throw e_1.error; }
+                }
+                // Handle index signiture member
+                if (membersMap.has(INDEX_SIGNITUTRE_MEMBER)) {
+                    var indexTypes = Array.from(membersMap.get(INDEX_SIGNITUTRE_MEMBER));
+                    var indexType = indexTypes[0];
+                    if (indexTypes.length > 1) {
+                        indexType = createUnionType(indexTypes);
+                    }
+                    var indexSigniture = ts.createIndexSignature([], [], indexMemberParameter, indexType);
+                    finalMembers.push(indexSigniture);
+                }
+                // Generate one single type literal node
+                return ts.createTypeLiteralNode(finalMembers);
+                var e_1, _d;
+            }
+            /**
+             * Create a union type from multiple type nodes
+             * @param types
+             */
+            function createUnionType(types) {
+                // first dedupe literal types
+                // TODO: this only works if all types are primitive types like string or number
+                var uniqueTypes = _.uniqBy(types, function (type) { return type.kind; });
+                return ts.createUnionOrIntersectionTypeNode(ts.SyntaxKind.UnionType, uniqueTypes);
+            }
+        };
+    };
+}
+exports.collapseIntersectionInterfacesTransformFactoryFactory = collapseIntersectionInterfacesTransformFactoryFactory;
+//# sourceMappingURL=collapse-intersection-interfaces-transform.js.map
\ No newline at end of file
diff --git a/dist/transforms/collapse-intersection-interfaces-transform.js.map b/dist/transforms/collapse-intersection-interfaces-transform.js.map
new file mode 100644
index 0000000..8f6e294
--- /dev/null
+++ b/dist/transforms/collapse-intersection-interfaces-transform.js.map
@@ -0,0 +1 @@
+{"version":3,"file":"collapse-intersection-interfaces-transform.js","sourceRoot":"/Users/ethans/Documents/workspace/src/","sources":["transforms/collapse-intersection-interfaces-transform.ts"],"names":[],"mappings":"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"}
\ No newline at end of file
diff --git a/dist/transforms/react-js-make-props-and-state-transform.d.ts b/dist/transforms/react-js-make-props-and-state-transform.d.ts
new file mode 100644
index 0000000..3dd9d0c
--- /dev/null
+++ b/dist/transforms/react-js-make-props-and-state-transform.d.ts
@@ -0,0 +1,8 @@
+import * as ts from 'typescript';
+export declare type Factory = ts.TransformerFactory<ts.SourceFile>;
+/**
+ * Get transform for transforming React code originally written in JS which does not have
+ * props and state generic types
+ * This transform will remove React component static "propTypes" member during transform
+ */
+export declare function reactJSMakePropsAndStateInterfaceTransformFactoryFactory(typeChecker: ts.TypeChecker): Factory;
diff --git a/dist/transforms/react-js-make-props-and-state-transform.js b/dist/transforms/react-js-make-props-and-state-transform.js
new file mode 100644
index 0000000..108f62c
--- /dev/null
+++ b/dist/transforms/react-js-make-props-and-state-transform.js
@@ -0,0 +1,217 @@
+"use strict";
+var __values = (this && this.__values) || function (o) {
+    var m = typeof Symbol === "function" && o[Symbol.iterator], i = 0;
+    if (m) return m.call(o);
+    return {
+        next: function () {
+            if (o && i >= o.length) o = void 0;
+            return { value: o && o[i++], done: !o };
+        }
+    };
+};
+Object.defineProperty(exports, "__esModule", { value: true });
+var ts = require("typescript");
+var _ = require("lodash");
+var helpers = require("../helpers");
+/**
+ * Get transform for transforming React code originally written in JS which does not have
+ * props and state generic types
+ * This transform will remove React component static "propTypes" member during transform
+ */
+function reactJSMakePropsAndStateInterfaceTransformFactoryFactory(typeChecker) {
+    return function reactJSMakePropsAndStateInterfaceTransformFactory(context) {
+        return function reactJSMakePropsAndStateInterfaceTransform(sourceFile) {
+            var visited = visitSourceFile(sourceFile, typeChecker);
+            ts.addEmitHelpers(visited, context.readEmitHelpers());
+            return visited;
+        };
+    };
+}
+exports.reactJSMakePropsAndStateInterfaceTransformFactoryFactory = reactJSMakePropsAndStateInterfaceTransformFactoryFactory;
+function visitSourceFile(sourceFile, typeChecker) {
+    var newSourceFile = sourceFile;
+    try {
+        for (var _a = __values(sourceFile.statements), _b = _a.next(); !_b.done; _b = _a.next()) {
+            var statement = _b.value;
+            if (ts.isClassDeclaration(statement) && helpers.isReactComponent(statement, typeChecker)) {
+                newSourceFile = visitReactClassDeclaration(statement, newSourceFile, typeChecker);
+            }
+        }
+    }
+    catch (e_1_1) { e_1 = { error: e_1_1 }; }
+    finally {
+        try {
+            if (_b && !_b.done && (_c = _a.return)) _c.call(_a);
+        }
+        finally { if (e_1) throw e_1.error; }
+    }
+    return newSourceFile;
+    var e_1, _c;
+}
+function visitReactClassDeclaration(classDeclaration, sourceFile, typeChecker) {
+    if (!classDeclaration.heritageClauses || !classDeclaration.heritageClauses.length) {
+        return sourceFile;
+    }
+    var className = classDeclaration && classDeclaration.name && classDeclaration.name.getText(sourceFile);
+    var propType = getPropsTypeOfReactComponentClass(classDeclaration, sourceFile);
+    var stateType = getStateTypeOfReactComponentClass(classDeclaration, typeChecker);
+    var shouldMakePropTypeDeclaration = propType.members.length > 0;
+    var shouldMakeStateTypeDeclaration = !isStateTypeMemberEmpty(stateType);
+    var propTypeName = className + "Props";
+    var stateTypeName = className + "State";
+    var propTypeDeclaration = ts.createTypeAliasDeclaration([], [], propTypeName, [], propType);
+    var stateTypeDeclaration = ts.createTypeAliasDeclaration([], [], stateTypeName, [], stateType);
+    var propTypeRef = ts.createTypeReferenceNode(propTypeName, []);
+    var stateTypeRef = ts.createTypeReferenceNode(stateTypeName, []);
+    var newClassDeclaration = getNewReactClassDeclaration(classDeclaration, shouldMakePropTypeDeclaration ? propTypeRef : propType, shouldMakeStateTypeDeclaration ? stateTypeRef : stateType);
+    var allTypeDeclarations = [];
+    if (shouldMakePropTypeDeclaration)
+        allTypeDeclarations.push(propTypeDeclaration);
+    if (shouldMakeStateTypeDeclaration)
+        allTypeDeclarations.push(stateTypeDeclaration);
+    var statements = helpers.insertBefore(sourceFile.statements, classDeclaration, allTypeDeclarations);
+    statements = helpers.replaceItem(statements, classDeclaration, newClassDeclaration);
+    return ts.updateSourceFileNode(sourceFile, statements);
+}
+function getNewReactClassDeclaration(classDeclaration, propTypeRef, stateTypeRef) {
+    if (!classDeclaration.heritageClauses || !classDeclaration.heritageClauses.length) {
+        return classDeclaration;
+    }
+    var firstHeritageClause = classDeclaration.heritageClauses[0];
+    var newFirstHeritageClauseTypes = helpers.replaceItem(firstHeritageClause.types, firstHeritageClause.types[0], ts.updateExpressionWithTypeArguments(firstHeritageClause.types[0], [propTypeRef, stateTypeRef], firstHeritageClause.types[0].expression));
+    var newHeritageClauses = helpers.replaceItem(classDeclaration.heritageClauses, firstHeritageClause, ts.updateHeritageClause(firstHeritageClause, newFirstHeritageClauseTypes));
+    return ts.updateClassDeclaration(classDeclaration, classDeclaration.decorators, classDeclaration.modifiers, classDeclaration.name, classDeclaration.typeParameters, newHeritageClauses, classDeclaration.members);
+}
+function getPropsTypeOfReactComponentClass(classDeclaration, sourceFile) {
+    var staticPropTypesMember = _.find(classDeclaration.members, function (member) {
+        return (ts.isPropertyDeclaration(member) &&
+            helpers.hasStaticModifier(member) &&
+            helpers.isPropTypesMember(member, sourceFile));
+    });
+    if (staticPropTypesMember !== undefined &&
+        ts.isPropertyDeclaration(staticPropTypesMember) && // check to satisfy type checker
+        staticPropTypesMember.initializer &&
+        ts.isObjectLiteralExpression(staticPropTypesMember.initializer)) {
+        return helpers.buildInterfaceFromPropTypeObjectLiteral(staticPropTypesMember.initializer);
+    }
+    var staticPropTypesGetterMember = _.find(classDeclaration.members, function (member) {
+        return (ts.isGetAccessorDeclaration(member) &&
+            helpers.hasStaticModifier(member) &&
+            helpers.isPropTypesMember(member, sourceFile));
+    });
+    if (staticPropTypesGetterMember !== undefined &&
+        ts.isGetAccessorDeclaration(staticPropTypesGetterMember) // check to satisfy typechecker
+    ) {
+        var returnStatement = _.find(staticPropTypesGetterMember.body.statements, function (statement) {
+            return ts.isReturnStatement(statement);
+        });
+        if (returnStatement !== undefined &&
+            ts.isReturnStatement(returnStatement) && // check to satisfy typechecker
+            returnStatement.expression &&
+            ts.isObjectLiteralExpression(returnStatement.expression)) {
+            return helpers.buildInterfaceFromPropTypeObjectLiteral(returnStatement.expression);
+        }
+    }
+    return ts.createTypeLiteralNode([]);
+}
+function getStateTypeOfReactComponentClass(classDeclaration, typeChecker) {
+    var initialState = getInitialStateFromClassDeclaration(classDeclaration, typeChecker);
+    var initialStateIsVoid = initialState.kind === ts.SyntaxKind.VoidKeyword;
+    var collectedStateTypes = getStateLookingForSetStateCalls(classDeclaration, typeChecker);
+    if (!collectedStateTypes.length && initialStateIsVoid) {
+        return ts.createTypeLiteralNode([]);
+    }
+    if (!initialStateIsVoid) {
+        collectedStateTypes.push(initialState);
+    }
+    return ts.createUnionOrIntersectionTypeNode(ts.SyntaxKind.IntersectionType, collectedStateTypes);
+}
+/**
+ * Get initial state of a React component looking for state value initially set
+ * @param classDeclaration
+ * @param typeChecker
+ */
+function getInitialStateFromClassDeclaration(classDeclaration, typeChecker) {
+    // initial state class member
+    var initialStateMember = _.find(classDeclaration.members, function (member) {
+        try {
+            return ts.isPropertyDeclaration(member) && member.name && member.name.getText() === 'state';
+        }
+        catch (e) {
+            return false;
+        }
+    });
+    if (initialStateMember && ts.isPropertyDeclaration(initialStateMember) && initialStateMember.initializer) {
+        var type = typeChecker.getTypeAtLocation(initialStateMember.initializer);
+        return typeChecker.typeToTypeNode(type);
+    }
+    // Initial state in constructor
+    var constructor = _.find(classDeclaration.members, function (member) { return member.kind === ts.SyntaxKind.Constructor; });
+    if (constructor && constructor.body) {
+        try {
+            for (var _a = __values(constructor.body.statements), _b = _a.next(); !_b.done; _b = _a.next()) {
+                var statement = _b.value;
+                if (ts.isExpressionStatement(statement) &&
+                    ts.isBinaryExpression(statement.expression) &&
+                    statement.expression.left.getText() === 'this.state') {
+                    return typeChecker.typeToTypeNode(typeChecker.getTypeAtLocation(statement.expression.right));
+                }
+            }
+        }
+        catch (e_2_1) { e_2 = { error: e_2_1 }; }
+        finally {
+            try {
+                if (_b && !_b.done && (_c = _a.return)) _c.call(_a);
+            }
+            finally { if (e_2) throw e_2.error; }
+        }
+    }
+    // No initial state, fall back to void
+    return ts.createKeywordTypeNode(ts.SyntaxKind.VoidKeyword);
+    var e_2, _c;
+}
+/**
+ * Look for setState() function calls to collect the state interface in a React class component
+ * @param classDeclaration
+ * @param typeChecker
+ */
+function getStateLookingForSetStateCalls(classDeclaration, typeChecker) {
+    var typeNodes = [];
+    try {
+        for (var _a = __values(classDeclaration.members), _b = _a.next(); !_b.done; _b = _a.next()) {
+            var member = _b.value;
+            if (member && ts.isMethodDeclaration(member) && member.body) {
+                lookForSetState(member.body);
+            }
+        }
+    }
+    catch (e_3_1) { e_3 = { error: e_3_1 }; }
+    finally {
+        try {
+            if (_b && !_b.done && (_c = _a.return)) _c.call(_a);
+        }
+        finally { if (e_3) throw e_3.error; }
+    }
+    return typeNodes;
+    function lookForSetState(node) {
+        ts.forEachChild(node, lookForSetState);
+        if (ts.isExpressionStatement(node) &&
+            ts.isCallExpression(node.expression) &&
+            node.expression.expression.getText().match(/setState/)) {
+            var type = typeChecker.getTypeAtLocation(node.expression.arguments[0]);
+            typeNodes.push(typeChecker.typeToTypeNode(type));
+        }
+    }
+    var e_3, _c;
+}
+function isStateTypeMemberEmpty(stateType) {
+    // Only need to handle TypeLiteralNode & IntersectionTypeNode
+    if (ts.isTypeLiteralNode(stateType)) {
+        return stateType.members.length === 0;
+    }
+    if (!ts.isIntersectionTypeNode(stateType)) {
+        return true;
+    }
+    return stateType.types.every(isStateTypeMemberEmpty);
+}
+//# sourceMappingURL=react-js-make-props-and-state-transform.js.map
\ No newline at end of file
diff --git a/dist/transforms/react-js-make-props-and-state-transform.js.map b/dist/transforms/react-js-make-props-and-state-transform.js.map
new file mode 100644
index 0000000..84567f8
--- /dev/null
+++ b/dist/transforms/react-js-make-props-and-state-transform.js.map
@@ -0,0 +1 @@
+{"version":3,"file":"react-js-make-props-and-state-transform.js","sourceRoot":"/Users/ethans/Documents/workspace/src/","sources":["transforms/react-js-make-props-and-state-transform.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,+BAAiC;AACjC,0BAA4B;AAC5B,oCAAsC;AAItC;;;;GAIG;AACH,kEAAyE,WAA2B;IAChG,OAAO,2DAA2D,OAAiC;QAC/F,OAAO,oDAAoD,UAAyB;YAChF,IAAM,OAAO,GAAG,eAAe,CAAC,UAAU,EAAE,WAAW,CAAC,CAAC;YACzD,EAAE,CAAC,cAAc,CAAC,OAAO,EAAE,OAAO,CAAC,eAAe,EAAE,CAAC,CAAC;YAEtD,OAAO,OAAO,CAAC;QACnB,CAAC,CAAC;IACN,CAAC,CAAC;AACN,CAAC;AATD,4HASC;AAED,yBAAyB,UAAyB,EAAE,WAA2B;IAC3E,IAAI,aAAa,GAAG,UAAU,CAAC;;QAC/B,KAAwB,IAAA,KAAA,SAAA,UAAU,CAAC,UAAU,CAAA,gBAAA;YAAxC,IAAM,SAAS,WAAA;YAChB,IAAI,EAAE,CAAC,kBAAkB,CAAC,SAAS,CAAC,IAAI,OAAO,CAAC,gBAAgB,CAAC,SAAS,EAAE,WAAW,CAAC,EAAE;gBACtF,aAAa,GAAG,0BAA0B,CAAC,SAAS,EAAE,aAAa,EAAE,WAAW,CAAC,CAAC;aACrF;SACJ;;;;;;;;;IAED,OAAO,aAAa,CAAC;;AACzB,CAAC;AAED,oCACI,gBAAqC,EACrC,UAAyB,EACzB,WAA2B;IAE3B,IAAI,CAAC,gBAAgB,CAAC,eAAe,IAAI,CAAC,gBAAgB,CAAC,eAAe,CAAC,MAAM,EAAE;QAC/E,OAAO,UAAU,CAAC;KACrB;IACD,IAAM,SAAS,GAAG,gBAAgB,IAAI,gBAAgB,CAAC,IAAI,IAAI,gBAAgB,CAAC,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;IACzG,IAAM,QAAQ,GAAG,iCAAiC,CAAC,gBAAgB,EAAE,UAAU,CAAC,CAAC;IACjF,IAAM,SAAS,GAAG,iCAAiC,CAAC,gBAAgB,EAAE,WAAW,CAAC,CAAC;IACnF,IAAM,6BAA6B,GAAG,QAAQ,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC;IAClE,IAAM,8BAA8B,GAAG,CAAC,sBAAsB,CAAC,SAAS,CAAC,CAAC;IAC1E,IAAM,YAAY,GAAM,SAAS,UAAO,CAAC;IACzC,IAAM,aAAa,GAAM,SAAS,UAAO,CAAC;IAC1C,IAAM,mBAAmB,GAAG,EAAE,CAAC,0BAA0B,CAAC,EAAE,EAAE,EAAE,EAAE,YAAY,EAAE,EAAE,EAAE,QAAQ,CAAC,CAAC;IAC9F,IAAM,oBAAoB,GAAG,EAAE,CAAC,0BAA0B,CAAC,EAAE,EAAE,EAAE,EAAE,aAAa,EAAE,EAAE,EAAE,SAAS,CAAC,CAAC;IACjG,IAAM,WAAW,GAAG,EAAE,CAAC,uBAAuB,CAAC,YAAY,EAAE,EAAE,CAAC,CAAC;IACjE,IAAM,YAAY,GAAG,EAAE,CAAC,uBAAuB,CAAC,aAAa,EAAE,EAAE,CAAC,CAAC;IAEnE,IAAM,mBAAmB,GAAG,2BAA2B,CACnD,gBAAgB,EAChB,6BAA6B,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,QAAQ,EACtD,8BAA8B,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,SAAS,CAC5D,CAAC;IAEF,IAAM,mBAAmB,GAAG,EAAE,CAAC;IAC/B,IAAI,6BAA6B;QAAE,mBAAmB,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC;IACjF,IAAI,8BAA8B;QAAE,mBAAmB,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC;IAEnF,IAAI,UAAU,GAAG,OAAO,CAAC,YAAY,CAAC,UAAU,CAAC,UAAU,EAAE,gBAAgB,EAAE,mBAAmB,CAAC,CAAC;IACpG,UAAU,GAAG,OAAO,CAAC,WAAW,CAAC,UAAU,EAAE,gBAAgB,EAAE,mBAAmB,CAAC,CAAC;IACpF,OAAO,EAAE,CAAC,oBAAoB,CAAC,UAAU,EAAE,UAAU,CAAC,CAAC;AAC3D,CAAC;AAED,qCACI,gBAAqC,EACrC,WAAwB,EACxB,YAAyB;IAEzB,IAAI,CAAC,gBAAgB,CAAC,eAAe,IAAI,CAAC,gBAAgB,CAAC,eAAe,CAAC,MAAM,EAAE;QAC/E,OAAO,gBAAgB,CAAC;KAC3B;IAED,IAAM,mBAAmB,GAAG,gBAAgB,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;IAEhE,IAAM,2BAA2B,GAAG,OAAO,CAAC,WAAW,CACnD,mBAAmB,CAAC,KAAK,EACzB,mBAAmB,CAAC,KAAK,CAAC,CAAC,CAAC,EAC5B,EAAE,CAAC,iCAAiC,CAChC,mBAAmB,CAAC,KAAK,CAAC,CAAC,CAAC,EAC5B,CAAC,WAAW,EAAE,YAAY,CAAC,EAC3B,mBAAmB,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,UAAU,CAC1C,CACJ,CAAC;IAEF,IAAM,kBAAkB,GAAG,OAAO,CAAC,WAAW,CAC1C,gBAAgB,CAAC,eAAe,EAChC,mBAAmB,EACnB,EAAE,CAAC,oBAAoB,CAAC,mBAAmB,EAAE,2BAA2B,CAAC,CAC5E,CAAC;IAEF,OAAO,EAAE,CAAC,sBAAsB,CAC5B,gBAAgB,EAChB,gBAAgB,CAAC,UAAU,EAC3B,gBAAgB,CAAC,SAAS,EAC1B,gBAAgB,CAAC,IAAI,EACrB,gBAAgB,CAAC,cAAc,EAC/B,kBAAkB,EAClB,gBAAgB,CAAC,OAAO,CAC3B,CAAC;AACN,CAAC;AAED,2CACI,gBAAqC,EACrC,UAAyB;IAEzB,IAAM,qBAAqB,GAAG,CAAC,CAAC,IAAI,CAAC,gBAAgB,CAAC,OAAO,EAAE,UAAA,MAAM;QACjE,OAAO,CACH,EAAE,CAAC,qBAAqB,CAAC,MAAM,CAAC;YAChC,OAAO,CAAC,iBAAiB,CAAC,MAAM,CAAC;YACjC,OAAO,CAAC,iBAAiB,CAAC,MAAM,EAAE,UAAU,CAAC,CAChD,CAAC;IACN,CAAC,CAAC,CAAC;IAEH,IACI,qBAAqB,KAAK,SAAS;QACnC,EAAE,CAAC,qBAAqB,CAAC,qBAAqB,CAAC,IAAI,gCAAgC;QACnF,qBAAqB,CAAC,WAAW;QACjC,EAAE,CAAC,yBAAyB,CAAC,qBAAqB,CAAC,WAAW,CAAC,EACjE;QACE,OAAO,OAAO,CAAC,uCAAuC,CAAC,qBAAqB,CAAC,WAAW,CAAC,CAAC;KAC7F;IAED,IAAM,2BAA2B,GAAG,CAAC,CAAC,IAAI,CAAC,gBAAgB,CAAC,OAAO,EAAE,UAAA,MAAM;QACvE,OAAO,CACH,EAAE,CAAC,wBAAwB,CAAC,MAAM,CAAC;YACnC,OAAO,CAAC,iBAAiB,CAAC,MAAM,CAAC;YACjC,OAAO,CAAC,iBAAiB,CAAC,MAAM,EAAE,UAAU,CAAC,CAChD,CAAC;IACN,CAAC,CAAC,CAAC;IAEH,IACI,2BAA2B,KAAK,SAAS;QACzC,EAAE,CAAC,wBAAwB,CAAC,2BAA2B,CAAC,CAAC,+BAA+B;MAC1F;QACE,IAAM,eAAe,GAAG,CAAC,CAAC,IAAI,CAAC,2BAA2B,CAAC,IAAK,CAAC,UAAU,EAAE,UAAA,SAAS;YAClF,OAAA,EAAE,CAAC,iBAAiB,CAAC,SAAS,CAAC;QAA/B,CAA+B,CAClC,CAAC;QACF,IACI,eAAe,KAAK,SAAS;YAC7B,EAAE,CAAC,iBAAiB,CAAC,eAAe,CAAC,IAAI,+BAA+B;YACxE,eAAe,CAAC,UAAU;YAC1B,EAAE,CAAC,yBAAyB,CAAC,eAAe,CAAC,UAAU,CAAC,EAC1D;YACE,OAAO,OAAO,CAAC,uCAAuC,CAAC,eAAe,CAAC,UAAU,CAAC,CAAC;SACtF;KACJ;IAED,OAAO,EAAE,CAAC,qBAAqB,CAAC,EAAE,CAAC,CAAC;AACxC,CAAC;AAED,2CACI,gBAAqC,EACrC,WAA2B;IAE3B,IAAM,YAAY,GAAG,mCAAmC,CAAC,gBAAgB,EAAE,WAAW,CAAC,CAAC;IACxF,IAAM,kBAAkB,GAAG,YAAY,CAAC,IAAI,KAAK,EAAE,CAAC,UAAU,CAAC,WAAW,CAAC;IAC3E,IAAM,mBAAmB,GAAG,+BAA+B,CAAC,gBAAgB,EAAE,WAAW,CAAC,CAAC;IAC3F,IAAI,CAAC,mBAAmB,CAAC,MAAM,IAAI,kBAAkB,EAAE;QACnD,OAAO,EAAE,CAAC,qBAAqB,CAAC,EAAE,CAAC,CAAC;KACvC;IACD,IAAI,CAAC,kBAAkB,EAAE;QACrB,mBAAmB,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;KAC1C;IAED,OAAO,EAAE,CAAC,iCAAiC,CAAC,EAAE,CAAC,UAAU,CAAC,gBAAgB,EAAE,mBAAmB,CAAC,CAAC;AACrG,CAAC;AAED;;;;GAIG;AACH,6CACI,gBAAqC,EACrC,WAA2B;IAE3B,6BAA6B;IAE7B,IAAM,kBAAkB,GAAG,CAAC,CAAC,IAAI,CAAC,gBAAgB,CAAC,OAAO,EAAE,UAAA,MAAM;QAC9D,IAAI;YACA,OAAO,EAAE,CAAC,qBAAqB,CAAC,MAAM,CAAC,IAAI,MAAM,CAAC,IAAI,IAAI,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,KAAK,OAAO,CAAC;SAC/F;QAAC,OAAO,CAAC,EAAE;YACR,OAAO,KAAK,CAAC;SAChB;IACL,CAAC,CAAC,CAAC;IAEH,IAAI,kBAAkB,IAAI,EAAE,CAAC,qBAAqB,CAAC,kBAAkB,CAAC,IAAI,kBAAkB,CAAC,WAAW,EAAE;QACtG,IAAM,IAAI,GAAG,WAAW,CAAC,iBAAiB,CAAC,kBAAkB,CAAC,WAAW,CAAE,CAAC;QAE5E,OAAO,WAAW,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC;KAC3C;IAED,+BAA+B;IAC/B,IAAM,WAAW,GAAG,CAAC,CAAC,IAAI,CAAC,gBAAgB,CAAC,OAAO,EAAE,UAAA,MAAM,IAAI,OAAA,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC,UAAU,CAAC,WAAW,EAAzC,CAAyC,CAEzF,CAAC;IAEhB,IAAI,WAAW,IAAI,WAAW,CAAC,IAAI,EAAE;;YACjC,KAAwB,IAAA,KAAA,SAAA,WAAW,CAAC,IAAI,CAAC,UAAU,CAAA,gBAAA;gBAA9C,IAAM,SAAS,WAAA;gBAChB,IACI,EAAE,CAAC,qBAAqB,CAAC,SAAS,CAAC;oBACnC,EAAE,CAAC,kBAAkB,CAAC,SAAS,CAAC,UAAU,CAAC;oBAC3C,SAAS,CAAC,UAAU,CAAC,IAAI,CAAC,OAAO,EAAE,KAAK,YAAY,EACtD;oBACE,OAAO,WAAW,CAAC,cAAc,CAAC,WAAW,CAAC,iBAAiB,CAAC,SAAS,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC;iBAChG;aACJ;;;;;;;;;KACJ;IAED,sCAAsC;IACtC,OAAO,EAAE,CAAC,qBAAqB,CAAC,EAAE,CAAC,UAAU,CAAC,WAAW,CAAC,CAAC;;AAC/D,CAAC;AAED;;;;GAIG;AACH,yCACI,gBAAqC,EACrC,WAA2B;IAE3B,IAAM,SAAS,GAAkB,EAAE,CAAC;;QACpC,KAAqB,IAAA,KAAA,SAAA,gBAAgB,CAAC,OAAO,CAAA,gBAAA;YAAxC,IAAM,MAAM,WAAA;YACb,IAAI,MAAM,IAAI,EAAE,CAAC,mBAAmB,CAAC,MAAM,CAAC,IAAI,MAAM,CAAC,IAAI,EAAE;gBACzD,eAAe,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;aAChC;SACJ;;;;;;;;;IAED,OAAO,SAAS,CAAC;IAEjB,yBAAyB,IAAa;QAClC,EAAE,CAAC,YAAY,CAAC,IAAI,EAAE,eAAe,CAAC,CAAC;QACvC,IACI,EAAE,CAAC,qBAAqB,CAAC,IAAI,CAAC;YAC9B,EAAE,CAAC,gBAAgB,CAAC,IAAI,CAAC,UAAU,CAAC;YACpC,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,OAAO,EAAE,CAAC,KAAK,CAAC,UAAU,CAAC,EACxD;YACE,IAAM,IAAI,GAAG,WAAW,CAAC,iBAAiB,CAAC,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;YACzE,SAAS,CAAC,IAAI,CAAC,WAAW,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC,CAAC;SACpD;IACL,CAAC;;AACL,CAAC;AAED,gCAAgC,SAAsB;IAClD,6DAA6D;IAC7D,IAAI,EAAE,CAAC,iBAAiB,CAAC,SAAS,CAAC,EAAE;QACjC,OAAO,SAAS,CAAC,OAAO,CAAC,MAAM,KAAK,CAAC,CAAC;KACzC;IAED,IAAI,CAAC,EAAE,CAAC,sBAAsB,CAAC,SAAS,CAAC,EAAE;QACvC,OAAO,IAAI,CAAC;KACf;IAED,OAAO,SAAS,CAAC,KAAK,CAAC,KAAK,CAAC,sBAAsB,CAAC,CAAC;AACzD,CAAC"}
\ No newline at end of file
diff --git a/dist/transforms/react-move-prop-types-to-class-transform.d.ts b/dist/transforms/react-move-prop-types-to-class-transform.d.ts
new file mode 100644
index 0000000..5f236a9
--- /dev/null
+++ b/dist/transforms/react-move-prop-types-to-class-transform.d.ts
@@ -0,0 +1,28 @@
+import * as ts from 'typescript';
+export declare type Factory = ts.TransformerFactory<ts.SourceFile>;
+/**
+ * Move Component.propTypes statements into class as a static member of the class
+ * if React component is defined using a class
+ *
+ * Note: This transform assumes React component declaration and propTypes assignment statement
+ * are both on root of the source file
+ *
+ * @example
+ * Before:
+ * class SomeComponent extends React.Component<{foo: number;}, {bar: string;}> {}
+ * SomeComponent.propTypes = { foo: React.PropTypes.string }
+ *
+ * After
+ * class SomeComponent extends React.Component<{foo: number;}, {bar: string;}> {
+ *   static propTypes = { foo: React.PropTypes.string }
+ * }
+ *
+ * @todo
+ * This is not supporting multiple statements for a single class yet
+ * ```
+ * class SomeComponent extends React.Component<{foo: number;}, {bar: string;}> {}
+ * SomeComponent.propTypes = { foo: React.PropTypes.string }
+ * SomeComponent.propTypes.bar = React.PropTypes.number;
+ * ```
+ */
+export declare function reactMovePropTypesToClassTransformFactoryFactory(typeChecker: ts.TypeChecker): Factory;
diff --git a/dist/transforms/react-move-prop-types-to-class-transform.js b/dist/transforms/react-move-prop-types-to-class-transform.js
new file mode 100644
index 0000000..08065fb
--- /dev/null
+++ b/dist/transforms/react-move-prop-types-to-class-transform.js
@@ -0,0 +1,123 @@
+"use strict";
+var __values = (this && this.__values) || function (o) {
+    var m = typeof Symbol === "function" && o[Symbol.iterator], i = 0;
+    if (m) return m.call(o);
+    return {
+        next: function () {
+            if (o && i >= o.length) o = void 0;
+            return { value: o && o[i++], done: !o };
+        }
+    };
+};
+var __read = (this && this.__read) || function (o, n) {
+    var m = typeof Symbol === "function" && o[Symbol.iterator];
+    if (!m) return o;
+    var i = m.call(o), r, ar = [], e;
+    try {
+        while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
+    }
+    catch (error) { e = { error: error }; }
+    finally {
+        try {
+            if (r && !r.done && (m = i["return"])) m.call(i);
+        }
+        finally { if (e) throw e.error; }
+    }
+    return ar;
+};
+var __spread = (this && this.__spread) || function () {
+    for (var ar = [], i = 0; i < arguments.length; i++) ar = ar.concat(__read(arguments[i]));
+    return ar;
+};
+Object.defineProperty(exports, "__esModule", { value: true });
+var ts = require("typescript");
+var _ = require("lodash");
+var helpers = require("../helpers");
+/**
+ * Move Component.propTypes statements into class as a static member of the class
+ * if React component is defined using a class
+ *
+ * Note: This transform assumes React component declaration and propTypes assignment statement
+ * are both on root of the source file
+ *
+ * @example
+ * Before:
+ * class SomeComponent extends React.Component<{foo: number;}, {bar: string;}> {}
+ * SomeComponent.propTypes = { foo: React.PropTypes.string }
+ *
+ * After
+ * class SomeComponent extends React.Component<{foo: number;}, {bar: string;}> {
+ *   static propTypes = { foo: React.PropTypes.string }
+ * }
+ *
+ * @todo
+ * This is not supporting multiple statements for a single class yet
+ * ```
+ * class SomeComponent extends React.Component<{foo: number;}, {bar: string;}> {}
+ * SomeComponent.propTypes = { foo: React.PropTypes.string }
+ * SomeComponent.propTypes.bar = React.PropTypes.number;
+ * ```
+ */
+function reactMovePropTypesToClassTransformFactoryFactory(typeChecker) {
+    return function reactMovePropTypesToClassTransformFactory(context) {
+        return function reactMovePropTypesToClassTransform(sourceFile) {
+            var visited = visitSourceFile(sourceFile, typeChecker);
+            ts.addEmitHelpers(visited, context.readEmitHelpers());
+            return visited;
+        };
+    };
+}
+exports.reactMovePropTypesToClassTransformFactoryFactory = reactMovePropTypesToClassTransformFactoryFactory;
+/**
+ * Make the move from propType statement to static member
+ * @param sourceFile
+ * @param typeChecker
+ */
+function visitSourceFile(sourceFile, typeChecker) {
+    var statements = sourceFile.statements;
+    // Look for propType assignment statements
+    var propTypeAssignments = statements.filter(function (statement) {
+        return helpers.isReactPropTypeAssignmentStatement(statement);
+    });
+    var _loop_1 = function (propTypeAssignment) {
+        // Look for the class declarations with the same name
+        var componentName = helpers.getComponentName(propTypeAssignment, sourceFile);
+        var classStatement = _.find(statements, function (statement) {
+            return ts.isClassDeclaration(statement) &&
+                statement.name !== undefined &&
+                statement.name.getText(sourceFile) === componentName;
+        }); // Type weirdness
+        // && helpers.isBinaryExpression(propTypeAssignment.expression) is redundant to satisfy the type checker
+        if (classStatement && ts.isBinaryExpression(propTypeAssignment.expression)) {
+            var newClassStatement = addStaticMemberToClass(classStatement, 'propTypes', propTypeAssignment.expression.right);
+            statements = ts.createNodeArray(helpers.replaceItem(statements, classStatement, newClassStatement));
+        }
+    };
+    try {
+        for (var propTypeAssignments_1 = __values(propTypeAssignments), propTypeAssignments_1_1 = propTypeAssignments_1.next(); !propTypeAssignments_1_1.done; propTypeAssignments_1_1 = propTypeAssignments_1.next()) {
+            var propTypeAssignment = propTypeAssignments_1_1.value;
+            _loop_1(propTypeAssignment);
+        }
+    }
+    catch (e_1_1) { e_1 = { error: e_1_1 }; }
+    finally {
+        try {
+            if (propTypeAssignments_1_1 && !propTypeAssignments_1_1.done && (_a = propTypeAssignments_1.return)) _a.call(propTypeAssignments_1);
+        }
+        finally { if (e_1) throw e_1.error; }
+    }
+    return ts.updateSourceFileNode(sourceFile, statements);
+    var e_1, _a;
+}
+/**
+ * Insert a new static member into a class
+ * @param classDeclaration
+ * @param name
+ * @param value
+ */
+function addStaticMemberToClass(classDeclaration, name, value) {
+    var staticModifier = ts.createToken(ts.SyntaxKind.StaticKeyword);
+    var propertyDeclaration = ts.createProperty([], [staticModifier], name, undefined, undefined, value);
+    return ts.updateClassDeclaration(classDeclaration, classDeclaration.decorators, classDeclaration.modifiers, classDeclaration.name, classDeclaration.typeParameters, ts.createNodeArray(classDeclaration.heritageClauses), ts.createNodeArray(__spread([propertyDeclaration], classDeclaration.members)));
+}
+//# sourceMappingURL=react-move-prop-types-to-class-transform.js.map
\ No newline at end of file
diff --git a/dist/transforms/react-move-prop-types-to-class-transform.js.map b/dist/transforms/react-move-prop-types-to-class-transform.js.map
new file mode 100644
index 0000000..362f7a5
--- /dev/null
+++ b/dist/transforms/react-move-prop-types-to-class-transform.js.map
@@ -0,0 +1 @@
+{"version":3,"file":"react-move-prop-types-to-class-transform.js","sourceRoot":"/Users/ethans/Documents/workspace/src/","sources":["transforms/react-move-prop-types-to-class-transform.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,+BAAiC;AACjC,0BAA4B;AAE5B,oCAAsC;AAItC;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,0DAAiE,WAA2B;IACxF,OAAO,mDAAmD,OAAiC;QACvF,OAAO,4CAA4C,UAAyB;YACxE,IAAM,OAAO,GAAG,eAAe,CAAC,UAAU,EAAE,WAAW,CAAC,CAAC;YACzD,EAAE,CAAC,cAAc,CAAC,OAAO,EAAE,OAAO,CAAC,eAAe,EAAE,CAAC,CAAC;YACtD,OAAO,OAAO,CAAC;QACnB,CAAC,CAAC;IACN,CAAC,CAAC;AACN,CAAC;AARD,4GAQC;AAED;;;;GAIG;AACH,yBAAyB,UAAyB,EAAE,WAA2B;IAC3E,IAAI,UAAU,GAAG,UAAU,CAAC,UAAU,CAAC;IAEvC,0CAA0C;IAC1C,IAAM,mBAAmB,GAAG,UAAU,CAAC,MAAM,CAAC,UAAA,SAAS;QACnD,OAAA,OAAO,CAAC,kCAAkC,CAAC,SAAS,CAAC;IAArD,CAAqD,CAC5B,CAAC;4BAEnB,kBAAkB;QACzB,qDAAqD;QACrD,IAAM,aAAa,GAAG,OAAO,CAAC,gBAAgB,CAAC,kBAAkB,EAAE,UAAU,CAAC,CAAC;QAE/E,IAAM,cAAc,GAAI,CAAC,CAAC,IAAI,CAC1B,UAAU,EACV,UAAA,SAAS;YACL,OAAA,EAAE,CAAC,kBAAkB,CAAC,SAAS,CAAC;gBAChC,SAAS,CAAC,IAAI,KAAK,SAAS;gBAC5B,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,KAAK,aAAa;QAFpD,CAEoD,CAC7B,CAAC,CAAC,iBAAiB;QAElD,wGAAwG;QACxG,IAAI,cAAc,IAAI,EAAE,CAAC,kBAAkB,CAAC,kBAAkB,CAAC,UAAU,CAAC,EAAE;YACxE,IAAM,iBAAiB,GAAG,sBAAsB,CAC5C,cAAc,EACd,WAAW,EACX,kBAAkB,CAAC,UAAU,CAAC,KAAK,CACtC,CAAC;YACF,UAAU,GAAG,EAAE,CAAC,eAAe,CAAC,OAAO,CAAC,WAAW,CAAC,UAAU,EAAE,cAAc,EAAE,iBAAiB,CAAC,CAAC,CAAC;SACvG;IACL,CAAC;;QArBD,KAAiC,IAAA,wBAAA,SAAA,mBAAmB,CAAA,wDAAA;YAA/C,IAAM,kBAAkB,gCAAA;oBAAlB,kBAAkB;SAqB5B;;;;;;;;;IAED,OAAO,EAAE,CAAC,oBAAoB,CAAC,UAAU,EAAE,UAAU,CAAC,CAAC;;AAC3D,CAAC;AAED;;;;;GAKG;AACH,gCAAgC,gBAAqC,EAAE,IAAY,EAAE,KAAoB;IACrG,IAAM,cAAc,GAAG,EAAE,CAAC,WAAW,CAAC,EAAE,CAAC,UAAU,CAAC,aAAa,CAAC,CAAC;IACnE,IAAM,mBAAmB,GAAG,EAAE,CAAC,cAAc,CAAC,EAAE,EAAE,CAAC,cAAc,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,SAAS,EAAE,KAAK,CAAC,CAAC;IACvG,OAAO,EAAE,CAAC,sBAAsB,CAC5B,gBAAgB,EAChB,gBAAgB,CAAC,UAAU,EAC3B,gBAAgB,CAAC,SAAS,EAC1B,gBAAgB,CAAC,IAAI,EACrB,gBAAgB,CAAC,cAAc,EAC/B,EAAE,CAAC,eAAe,CAAC,gBAAgB,CAAC,eAAe,CAAC,EACpD,EAAE,CAAC,eAAe,WAAE,mBAAmB,GAAK,gBAAgB,CAAC,OAAO,EAAE,CACzE,CAAC;AACN,CAAC"}
\ No newline at end of file
diff --git a/dist/transforms/react-remove-prop-types-assignment-transform.d.ts b/dist/transforms/react-remove-prop-types-assignment-transform.d.ts
new file mode 100644
index 0000000..3cbad54
--- /dev/null
+++ b/dist/transforms/react-remove-prop-types-assignment-transform.d.ts
@@ -0,0 +1,14 @@
+import * as ts from 'typescript';
+export declare type Factory = ts.TransformerFactory<ts.SourceFile>;
+/**
+ * Remove Component.propTypes statements
+ *
+ * @example
+ * Before:
+ * class SomeComponent extends React.Component<{foo: number;}, {bar: string;}> {}
+ * SomeComponent.propTypes = { foo: React.PropTypes.string }
+ *
+ * After
+ * class SomeComponent extends React.Component<{foo: number;}, {bar: string;}> {}
+ */
+export declare function reactRemovePropTypesAssignmentTransformFactoryFactory(typeChecker: ts.TypeChecker): Factory;
diff --git a/dist/transforms/react-remove-prop-types-assignment-transform.js b/dist/transforms/react-remove-prop-types-assignment-transform.js
new file mode 100644
index 0000000..9546468
--- /dev/null
+++ b/dist/transforms/react-remove-prop-types-assignment-transform.js
@@ -0,0 +1,26 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+var ts = require("typescript");
+var helpers = require("../helpers");
+/**
+ * Remove Component.propTypes statements
+ *
+ * @example
+ * Before:
+ * class SomeComponent extends React.Component<{foo: number;}, {bar: string;}> {}
+ * SomeComponent.propTypes = { foo: React.PropTypes.string }
+ *
+ * After
+ * class SomeComponent extends React.Component<{foo: number;}, {bar: string;}> {}
+ */
+function reactRemovePropTypesAssignmentTransformFactoryFactory(typeChecker) {
+    return function reactRemovePropTypesAssignmentTransformFactory(context) {
+        return function reactRemovePropTypesAssignmentTransform(sourceFile) {
+            var visited = ts.updateSourceFileNode(sourceFile, sourceFile.statements.filter(function (s) { return !helpers.isReactPropTypeAssignmentStatement(s); }));
+            ts.addEmitHelpers(visited, context.readEmitHelpers());
+            return visited;
+        };
+    };
+}
+exports.reactRemovePropTypesAssignmentTransformFactoryFactory = reactRemovePropTypesAssignmentTransformFactoryFactory;
+//# sourceMappingURL=react-remove-prop-types-assignment-transform.js.map
\ No newline at end of file
diff --git a/dist/transforms/react-remove-prop-types-assignment-transform.js.map b/dist/transforms/react-remove-prop-types-assignment-transform.js.map
new file mode 100644
index 0000000..e82bd62
--- /dev/null
+++ b/dist/transforms/react-remove-prop-types-assignment-transform.js.map
@@ -0,0 +1 @@
+{"version":3,"file":"react-remove-prop-types-assignment-transform.js","sourceRoot":"/Users/ethans/Documents/workspace/src/","sources":["transforms/react-remove-prop-types-assignment-transform.ts"],"names":[],"mappings":";;AAAA,+BAAiC;AAEjC,oCAAsC;AAItC;;;;;;;;;;GAUG;AACH,+DAAsE,WAA2B;IAC7F,OAAO,wDAAwD,OAAiC;QAC5F,OAAO,iDAAiD,UAAyB;YAC7E,IAAM,OAAO,GAAG,EAAE,CAAC,oBAAoB,CACnC,UAAU,EACV,UAAU,CAAC,UAAU,CAAC,MAAM,CAAC,UAAA,CAAC,IAAI,OAAA,CAAC,OAAO,CAAC,kCAAkC,CAAC,CAAC,CAAC,EAA9C,CAA8C,CAAC,CACpF,CAAC;YACF,EAAE,CAAC,cAAc,CAAC,OAAO,EAAE,OAAO,CAAC,eAAe,EAAE,CAAC,CAAC;YACtD,OAAO,OAAO,CAAC;QACnB,CAAC,CAAC;IACN,CAAC,CAAC;AACN,CAAC;AAXD,sHAWC"}
\ No newline at end of file
diff --git a/dist/transforms/react-remove-prop-types-import.d.ts b/dist/transforms/react-remove-prop-types-import.d.ts
new file mode 100644
index 0000000..39a2fbf
--- /dev/null
+++ b/dist/transforms/react-remove-prop-types-import.d.ts
@@ -0,0 +1,15 @@
+import * as ts from 'typescript';
+export declare type Factory = ts.TransformerFactory<ts.SourceFile>;
+/**
+ * Remove `import PropTypes from 'prop-types'` or
+ * `import { PropTypes } from 'react'`
+ *
+ * @example
+ * Before:
+ * import PropTypes from 'prop-types'
+ * import React, { PropTypes } from 'react'
+ *
+ * After:
+ * import React from 'react'
+ */
+export declare function reactRemovePropTypesImportTransformFactoryFactory(typeChecker: ts.TypeChecker): Factory;
diff --git a/dist/transforms/react-remove-prop-types-import.js b/dist/transforms/react-remove-prop-types-import.js
new file mode 100644
index 0000000..24efe1a
--- /dev/null
+++ b/dist/transforms/react-remove-prop-types-import.js
@@ -0,0 +1,52 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+var ts = require("typescript");
+/**
+ * Remove `import PropTypes from 'prop-types'` or
+ * `import { PropTypes } from 'react'`
+ *
+ * @example
+ * Before:
+ * import PropTypes from 'prop-types'
+ * import React, { PropTypes } from 'react'
+ *
+ * After:
+ * import React from 'react'
+ */
+function reactRemovePropTypesImportTransformFactoryFactory(typeChecker) {
+    return function reactRemovePropTypesImportTransformFactory(context) {
+        return function reactRemovePropTypesImportTransform(sourceFile) {
+            var visited = ts.updateSourceFileNode(sourceFile, sourceFile.statements
+                .filter(function (s) {
+                return !(ts.isImportDeclaration(s) &&
+                    ts.isStringLiteral(s.moduleSpecifier) &&
+                    s.moduleSpecifier.text === 'prop-types');
+            })
+                .map(updateReactImportIfNeeded));
+            ts.addEmitHelpers(visited, context.readEmitHelpers());
+            return visited;
+        };
+    };
+}
+exports.reactRemovePropTypesImportTransformFactoryFactory = reactRemovePropTypesImportTransformFactoryFactory;
+function updateReactImportIfNeeded(statement) {
+    if (!ts.isImportDeclaration(statement) ||
+        !ts.isStringLiteral(statement.moduleSpecifier) ||
+        statement.moduleSpecifier.text !== 'react' ||
+        !statement.importClause ||
+        !statement.importClause.namedBindings ||
+        !ts.isNamedImports(statement.importClause.namedBindings)) {
+        return statement;
+    }
+    var namedBindings = statement.importClause.namedBindings;
+    var newNamedBindingElements = namedBindings.elements.filter(function (elm) { return elm.name.text !== 'PropTypes'; });
+    if (newNamedBindingElements.length === namedBindings.elements.length) {
+        // Means it has no 'PropTypes' named import
+        return statement;
+    }
+    var newImportClause = ts.updateImportClause(statement.importClause, statement.importClause.name, newNamedBindingElements.length === 0
+        ? undefined
+        : ts.updateNamedImports(namedBindings, newNamedBindingElements));
+    return ts.updateImportDeclaration(statement, statement.decorators, statement.modifiers, newImportClause, statement.moduleSpecifier);
+}
+//# sourceMappingURL=react-remove-prop-types-import.js.map
\ No newline at end of file
diff --git a/dist/transforms/react-remove-prop-types-import.js.map b/dist/transforms/react-remove-prop-types-import.js.map
new file mode 100644
index 0000000..3cdb181
--- /dev/null
+++ b/dist/transforms/react-remove-prop-types-import.js.map
@@ -0,0 +1 @@
+{"version":3,"file":"react-remove-prop-types-import.js","sourceRoot":"/Users/ethans/Documents/workspace/src/","sources":["transforms/react-remove-prop-types-import.ts"],"names":[],"mappings":";;AAAA,+BAAiC;AAOjC;;;;;;;;;;;GAWG;AACH,2DAAkE,WAA2B;IACzF,OAAO,oDAAoD,OAAiC;QACxF,OAAO,6CAA6C,UAAyB;YACzE,IAAM,OAAO,GAAG,EAAE,CAAC,oBAAoB,CACnC,UAAU,EACV,UAAU,CAAC,UAAU;iBAChB,MAAM,CAAC,UAAA,CAAC;gBACL,OAAO,CAAC,CACJ,EAAE,CAAC,mBAAmB,CAAC,CAAC,CAAC;oBACzB,EAAE,CAAC,eAAe,CAAC,CAAC,CAAC,eAAe,CAAC;oBACrC,CAAC,CAAC,eAAe,CAAC,IAAI,KAAK,YAAY,CAC1C,CAAC;YACN,CAAC,CAAC;iBACD,GAAG,CAAC,yBAAyB,CAAC,CACtC,CAAC;YACF,EAAE,CAAC,cAAc,CAAC,OAAO,EAAE,OAAO,CAAC,eAAe,EAAE,CAAC,CAAC;YACtD,OAAO,OAAO,CAAC;QACnB,CAAC,CAAC;IACN,CAAC,CAAC;AACN,CAAC;AAnBD,8GAmBC;AAED,mCAAmC,SAAuB;IACtD,IACI,CAAC,EAAE,CAAC,mBAAmB,CAAC,SAAS,CAAC;QAClC,CAAC,EAAE,CAAC,eAAe,CAAC,SAAS,CAAC,eAAe,CAAC;QAC9C,SAAS,CAAC,eAAe,CAAC,IAAI,KAAK,OAAO;QAC1C,CAAC,SAAS,CAAC,YAAY;QACvB,CAAC,SAAS,CAAC,YAAY,CAAC,aAAa;QACrC,CAAC,EAAE,CAAC,cAAc,CAAC,SAAS,CAAC,YAAY,CAAC,aAAa,CAAC,EAC1D;QACE,OAAO,SAAS,CAAC;KACpB;IAED,IAAM,aAAa,GAAG,SAAS,CAAC,YAAY,CAAC,aAAa,CAAC;IAC3D,IAAM,uBAAuB,GAAG,aAAa,CAAC,QAAQ,CAAC,MAAM,CAAC,UAAA,GAAG,IAAI,OAAA,GAAG,CAAC,IAAI,CAAC,IAAI,KAAK,WAAW,EAA7B,CAA6B,CAAC,CAAC;IAEpG,IAAI,uBAAuB,CAAC,MAAM,KAAK,aAAa,CAAC,QAAQ,CAAC,MAAM,EAAE;QAClE,2CAA2C;QAC3C,OAAO,SAAS,CAAC;KACpB;IAED,IAAM,eAAe,GAAG,EAAE,CAAC,kBAAkB,CACzC,SAAS,CAAC,YAAY,EACtB,SAAS,CAAC,YAAY,CAAC,IAAI,EAC3B,uBAAuB,CAAC,MAAM,KAAK,CAAC;QAChC,CAAC,CAAC,SAAS;QACX,CAAC,CAAC,EAAE,CAAC,kBAAkB,CAAC,aAAa,EAAE,uBAAuB,CAAC,CACtE,CAAC;IAEF,OAAO,EAAE,CAAC,uBAAuB,CAC7B,SAAS,EACT,SAAS,CAAC,UAAU,EACpB,SAAS,CAAC,SAAS,EACnB,eAAe,EACf,SAAS,CAAC,eAAe,CAC5B,CAAC;AACN,CAAC"}
\ No newline at end of file
diff --git a/dist/transforms/react-remove-static-prop-types-member-transform.d.ts b/dist/transforms/react-remove-static-prop-types-member-transform.d.ts
new file mode 100644
index 0000000..480264e
--- /dev/null
+++ b/dist/transforms/react-remove-static-prop-types-member-transform.d.ts
@@ -0,0 +1,17 @@
+import * as ts from 'typescript';
+export declare type Factory = ts.TransformerFactory<ts.SourceFile>;
+/**
+ * Remove static propTypes
+ *
+ * @example
+ * Before:
+ * class SomeComponent extends React.Component<{foo: number;}, {bar: string;}> {
+ *   static propTypes = {
+ *      foo: React.PropTypes.number.isRequired,
+ *   }
+ * }
+ *
+ * After:
+ * class SomeComponent extends React.Component<{foo: number;}, {bar: string;}> {}
+ */
+export declare function reactRemoveStaticPropTypesMemberTransformFactoryFactory(typeChecker: ts.TypeChecker): Factory;
diff --git a/dist/transforms/react-remove-static-prop-types-member-transform.js b/dist/transforms/react-remove-static-prop-types-member-transform.js
new file mode 100644
index 0000000..a7e0d63
--- /dev/null
+++ b/dist/transforms/react-remove-static-prop-types-member-transform.js
@@ -0,0 +1,48 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+var ts = require("typescript");
+var helpers = require("../helpers");
+/**
+ * Remove static propTypes
+ *
+ * @example
+ * Before:
+ * class SomeComponent extends React.Component<{foo: number;}, {bar: string;}> {
+ *   static propTypes = {
+ *      foo: React.PropTypes.number.isRequired,
+ *   }
+ * }
+ *
+ * After:
+ * class SomeComponent extends React.Component<{foo: number;}, {bar: string;}> {}
+ */
+function reactRemoveStaticPropTypesMemberTransformFactoryFactory(typeChecker) {
+    return function reactRemoveStaticPropTypesMemberTransformFactory(context) {
+        return function reactRemoveStaticPropTypesMemberTransform(sourceFile) {
+            var visited = ts.visitEachChild(sourceFile, visitor, context);
+            ts.addEmitHelpers(visited, context.readEmitHelpers());
+            return visited;
+            function visitor(node) {
+                if (ts.isClassDeclaration(node) && helpers.isReactComponent(node, typeChecker)) {
+                    return ts.updateClassDeclaration(node, node.decorators, node.modifiers, node.name, node.typeParameters, ts.createNodeArray(node.heritageClauses), node.members.filter(function (member) {
+                        if (ts.isPropertyDeclaration(member) &&
+                            helpers.hasStaticModifier(member) &&
+                            helpers.isPropTypesMember(member, sourceFile)) {
+                            return false;
+                        }
+                        // propTypes getter
+                        if (ts.isGetAccessorDeclaration(member) &&
+                            helpers.hasStaticModifier(member) &&
+                            helpers.isPropTypesMember(member, sourceFile)) {
+                            return false;
+                        }
+                        return true;
+                    }));
+                }
+                return node;
+            }
+        };
+    };
+}
+exports.reactRemoveStaticPropTypesMemberTransformFactoryFactory = reactRemoveStaticPropTypesMemberTransformFactoryFactory;
+//# sourceMappingURL=react-remove-static-prop-types-member-transform.js.map
\ No newline at end of file
diff --git a/dist/transforms/react-remove-static-prop-types-member-transform.js.map b/dist/transforms/react-remove-static-prop-types-member-transform.js.map
new file mode 100644
index 0000000..0ab271b
--- /dev/null
+++ b/dist/transforms/react-remove-static-prop-types-member-transform.js.map
@@ -0,0 +1 @@
+{"version":3,"file":"react-remove-static-prop-types-member-transform.js","sourceRoot":"/Users/ethans/Documents/workspace/src/","sources":["transforms/react-remove-static-prop-types-member-transform.ts"],"names":[],"mappings":";;AAAA,+BAAiC;AAEjC,oCAAsC;AAItC;;;;;;;;;;;;;GAaG;AACH,iEAAwE,WAA2B;IAC/F,OAAO,0DAA0D,OAAiC;QAC9F,OAAO,mDAAmD,UAAyB;YAC/E,IAAM,OAAO,GAAG,EAAE,CAAC,cAAc,CAAC,UAAU,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;YAChE,EAAE,CAAC,cAAc,CAAC,OAAO,EAAE,OAAO,CAAC,eAAe,EAAE,CAAC,CAAC;YACtD,OAAO,OAAO,CAAC;YAEf,iBAAiB,IAAa;gBAC1B,IAAI,EAAE,CAAC,kBAAkB,CAAC,IAAI,CAAC,IAAI,OAAO,CAAC,gBAAgB,CAAC,IAAI,EAAE,WAAW,CAAC,EAAE;oBAC5E,OAAO,EAAE,CAAC,sBAAsB,CAC5B,IAAI,EACJ,IAAI,CAAC,UAAU,EACf,IAAI,CAAC,SAAS,EACd,IAAI,CAAC,IAAI,EACT,IAAI,CAAC,cAAc,EACnB,EAAE,CAAC,eAAe,CAAC,IAAI,CAAC,eAAe,CAAC,EACxC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,UAAA,MAAM;wBACtB,IACI,EAAE,CAAC,qBAAqB,CAAC,MAAM,CAAC;4BAChC,OAAO,CAAC,iBAAiB,CAAC,MAAM,CAAC;4BACjC,OAAO,CAAC,iBAAiB,CAAC,MAAM,EAAE,UAAU,CAAC,EAC/C;4BACE,OAAO,KAAK,CAAC;yBAChB;wBAED,mBAAmB;wBACnB,IACI,EAAE,CAAC,wBAAwB,CAAC,MAAM,CAAC;4BACnC,OAAO,CAAC,iBAAiB,CAAC,MAAM,CAAC;4BACjC,OAAO,CAAC,iBAAiB,CAAC,MAAM,EAAE,UAAU,CAAC,EAC/C;4BACE,OAAO,KAAK,CAAC;yBAChB;wBACD,OAAO,IAAI,CAAC;oBAChB,CAAC,CAAC,CACL,CAAC;iBACL;gBACD,OAAO,IAAI,CAAC;YAChB,CAAC;QACL,CAAC,CAAC;IACN,CAAC,CAAC;AACN,CAAC;AAzCD,0HAyCC"}
\ No newline at end of file
diff --git a/dist/transforms/react-stateless-function-make-props-transform.d.ts b/dist/transforms/react-stateless-function-make-props-transform.d.ts
new file mode 100644
index 0000000..7f10a84
--- /dev/null
+++ b/dist/transforms/react-stateless-function-make-props-transform.d.ts
@@ -0,0 +1,31 @@
+import * as ts from 'typescript';
+export declare type Factory = ts.TransformerFactory<ts.SourceFile>;
+/**
+ * Transform react stateless components
+ *
+ * @example
+ * Before:
+ * const Hello = ({ message }) => {
+ *   return <div>hello {message}</div>
+ * }
+ * // Or:
+ * // const Hello = ({ message }) => <div>hello {message}</div>
+ *
+ * Hello.propTypes = {
+ *   message: React.PropTypes.string,
+ * }
+ *
+ * After:
+ * Type HelloProps = {
+ *   message: string;
+ * }
+ *
+ * const Hello: React.SFC<HelloProps> = ({ message }) => {
+ *   return <div>hello {message}</div>
+ * }
+ *
+ * Hello.propTypes = {
+ *   message: React.PropTypes.string,
+ * }
+ */
+export declare function reactStatelessFunctionMakePropsTransformFactoryFactory(typeChecker: ts.TypeChecker): Factory;
diff --git a/dist/transforms/react-stateless-function-make-props-transform.js b/dist/transforms/react-stateless-function-make-props-transform.js
new file mode 100644
index 0000000..2864bfd
--- /dev/null
+++ b/dist/transforms/react-stateless-function-make-props-transform.js
@@ -0,0 +1,114 @@
+"use strict";
+var __values = (this && this.__values) || function (o) {
+    var m = typeof Symbol === "function" && o[Symbol.iterator], i = 0;
+    if (m) return m.call(o);
+    return {
+        next: function () {
+            if (o && i >= o.length) o = void 0;
+            return { value: o && o[i++], done: !o };
+        }
+    };
+};
+Object.defineProperty(exports, "__esModule", { value: true });
+var ts = require("typescript");
+var _ = require("lodash");
+var helpers = require("../helpers");
+/**
+ * Transform react stateless components
+ *
+ * @example
+ * Before:
+ * const Hello = ({ message }) => {
+ *   return <div>hello {message}</div>
+ * }
+ * // Or:
+ * // const Hello = ({ message }) => <div>hello {message}</div>
+ *
+ * Hello.propTypes = {
+ *   message: React.PropTypes.string,
+ * }
+ *
+ * After:
+ * Type HelloProps = {
+ *   message: string;
+ * }
+ *
+ * const Hello: React.SFC<HelloProps> = ({ message }) => {
+ *   return <div>hello {message}</div>
+ * }
+ *
+ * Hello.propTypes = {
+ *   message: React.PropTypes.string,
+ * }
+ */
+function reactStatelessFunctionMakePropsTransformFactoryFactory(typeChecker) {
+    return function reactStatelessFunctionMakePropsTransformFactory(context) {
+        return function reactStatelessFunctionMakePropsTransform(sourceFile) {
+            var visited = visitSourceFile(sourceFile, typeChecker);
+            ts.addEmitHelpers(visited, context.readEmitHelpers());
+            return visited;
+        };
+    };
+}
+exports.reactStatelessFunctionMakePropsTransformFactoryFactory = reactStatelessFunctionMakePropsTransformFactoryFactory;
+function visitSourceFile(sourceFile, typeChecker) {
+    // Look for propType assignment statements
+    var propTypeAssignments = sourceFile.statements.filter(function (statement) {
+        return helpers.isReactPropTypeAssignmentStatement(statement);
+    });
+    var newSourceFile = sourceFile;
+    var _loop_1 = function (propTypeAssignment) {
+        var componentName = helpers.getComponentName(propTypeAssignment, newSourceFile);
+        var funcComponent = _.find(newSourceFile.statements, function (s) {
+            return ((ts.isFunctionDeclaration(s) && s.name !== undefined && s.name.getText() === componentName) ||
+                (ts.isVariableStatement(s) && s.declarationList.declarations[0].name.getText() === componentName));
+        }); // Type weirdness
+        if (funcComponent) {
+            newSourceFile = visitReactStatelessComponent(funcComponent, propTypeAssignment, newSourceFile);
+        }
+    };
+    try {
+        for (var propTypeAssignments_1 = __values(propTypeAssignments), propTypeAssignments_1_1 = propTypeAssignments_1.next(); !propTypeAssignments_1_1.done; propTypeAssignments_1_1 = propTypeAssignments_1.next()) {
+            var propTypeAssignment = propTypeAssignments_1_1.value;
+            _loop_1(propTypeAssignment);
+        }
+    }
+    catch (e_1_1) { e_1 = { error: e_1_1 }; }
+    finally {
+        try {
+            if (propTypeAssignments_1_1 && !propTypeAssignments_1_1.done && (_a = propTypeAssignments_1.return)) _a.call(propTypeAssignments_1);
+        }
+        finally { if (e_1) throw e_1.error; }
+    }
+    return newSourceFile;
+    var e_1, _a;
+}
+function visitReactStatelessComponent(component, propTypesExpressionStatement, sourceFile) {
+    var arrowFuncComponent = helpers.convertReactStatelessFunctionToArrowFunction(component);
+    var componentName = arrowFuncComponent.declarationList.declarations[0].name.getText();
+    var componentInitializer = arrowFuncComponent.declarationList.declarations[0].initializer;
+    var propType = getPropTypesFromTypeAssignment(propTypesExpressionStatement);
+    var shouldMakePropTypeDeclaration = propType.members.length > 0;
+    var propTypeName = componentName + "Props";
+    var propTypeDeclaration = ts.createTypeAliasDeclaration([], [], propTypeName, [], propType);
+    var propTypeRef = ts.createTypeReferenceNode(propTypeName, []);
+    var componentType = ts.createTypeReferenceNode(ts.createQualifiedName(ts.createIdentifier('React'), 'SFC'), [
+        shouldMakePropTypeDeclaration ? propTypeRef : propType,
+    ]);
+    // replace component with ts stateless component
+    var typedComponent = ts.createVariableStatement(arrowFuncComponent.modifiers, ts.createVariableDeclarationList([ts.createVariableDeclaration(componentName, componentType, componentInitializer)], arrowFuncComponent.declarationList.flags));
+    var statements = shouldMakePropTypeDeclaration
+        ? helpers.insertBefore(sourceFile.statements, component, [propTypeDeclaration])
+        : sourceFile.statements;
+    statements = helpers.replaceItem(statements, component, typedComponent);
+    return ts.updateSourceFileNode(sourceFile, statements);
+}
+function getPropTypesFromTypeAssignment(propTypesExpressionStatement) {
+    if (propTypesExpressionStatement !== undefined &&
+        ts.isBinaryExpression(propTypesExpressionStatement.expression) &&
+        ts.isObjectLiteralExpression(propTypesExpressionStatement.expression.right)) {
+        return helpers.buildInterfaceFromPropTypeObjectLiteral(propTypesExpressionStatement.expression.right);
+    }
+    return ts.createTypeLiteralNode([]);
+}
+//# sourceMappingURL=react-stateless-function-make-props-transform.js.map
\ No newline at end of file
diff --git a/dist/transforms/react-stateless-function-make-props-transform.js.map b/dist/transforms/react-stateless-function-make-props-transform.js.map
new file mode 100644
index 0000000..08d9fca
--- /dev/null
+++ b/dist/transforms/react-stateless-function-make-props-transform.js.map
@@ -0,0 +1 @@
+{"version":3,"file":"react-stateless-function-make-props-transform.js","sourceRoot":"/Users/ethans/Documents/workspace/src/","sources":["transforms/react-stateless-function-make-props-transform.ts"],"names":[],"mappings":"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"}
\ No newline at end of file
diff --git a/package.json b/package.json
index 55994ac..6d66e5d 100644
--- a/package.json
+++ b/package.json
@@ -22,10 +22,16 @@
             ".ts": "<rootDir>/node_modules/ts-jest/preprocessor.js"
         },
         "testRegex": "(/tests/.*|(\\.|/)(test|spec))\\.(jsx?|tsx?)$",
-        "moduleFileExtensions": ["ts", "js"]
+        "moduleFileExtensions": [
+            "ts",
+            "js"
+        ]
     },
     "lint-staged": {
-        "*.{js,json,css,md,ts,tsx}": ["node_modules/.bin/prettier --write", "git add"]
+        "*.{js,json,css,md,ts,tsx}": [
+            "node_modules/.bin/prettier --write",
+            "git add"
+        ]
     },
     "bin": "dist/cli.js",
     "author": "Mohsen Azimi <me@azimi.me>",