|  | 
|  | 1 | +import * as ts from 'typescript'; | 
|  | 2 | +import * as _ from 'lodash'; | 
|  | 3 | + | 
|  | 4 | +import * as helpers from '../helpers'; | 
|  | 5 | + | 
|  | 6 | +export type Factory = ts.TransformerFactory<ts.SourceFile>; | 
|  | 7 | + | 
|  | 8 | +/** | 
|  | 9 | + * Remove `import PropTypes from 'prop-types'` or | 
|  | 10 | + * `import { PropTypes } from 'react'` | 
|  | 11 | + * | 
|  | 12 | + * @example | 
|  | 13 | + * Before: | 
|  | 14 | + * import PropTypes from 'prop-types' | 
|  | 15 | + * import React, { PropTypes } from 'react' | 
|  | 16 | + * | 
|  | 17 | + * After: | 
|  | 18 | + * import React from 'react' | 
|  | 19 | + */ | 
|  | 20 | +export function reactRemovePropTypesImportTransformFactoryFactory(typeChecker: ts.TypeChecker): Factory { | 
|  | 21 | +    return function reactRemovePropTypesImportTransformFactory(context: ts.TransformationContext) { | 
|  | 22 | +        return function reactRemovePropTypesImportTransform(sourceFile: ts.SourceFile) { | 
|  | 23 | +            return ts.updateSourceFileNode( | 
|  | 24 | +                sourceFile, | 
|  | 25 | +                sourceFile.statements | 
|  | 26 | +                    .filter(s => { | 
|  | 27 | +                        return !( | 
|  | 28 | +                            ts.isImportDeclaration(s) && | 
|  | 29 | +                            ts.isStringLiteral(s.moduleSpecifier) && | 
|  | 30 | +                            s.moduleSpecifier.text === 'prop-types' | 
|  | 31 | +                        ); | 
|  | 32 | +                    }) | 
|  | 33 | +                    .map(updateReactImportIfNeeded), | 
|  | 34 | +            ); | 
|  | 35 | +        }; | 
|  | 36 | +    }; | 
|  | 37 | +} | 
|  | 38 | + | 
|  | 39 | +function updateReactImportIfNeeded(statement: ts.Statement) { | 
|  | 40 | +    if ( | 
|  | 41 | +        !ts.isImportDeclaration(statement) || | 
|  | 42 | +        !ts.isStringLiteral(statement.moduleSpecifier) || | 
|  | 43 | +        statement.moduleSpecifier.text !== 'react' || | 
|  | 44 | +        !statement.importClause || | 
|  | 45 | +        !statement.importClause.namedBindings || | 
|  | 46 | +        !ts.isNamedImports(statement.importClause.namedBindings) | 
|  | 47 | +    ) { | 
|  | 48 | +        return statement; | 
|  | 49 | +    } | 
|  | 50 | + | 
|  | 51 | +    const namedBindings = statement.importClause.namedBindings; | 
|  | 52 | +    const newNamedBindingElements = namedBindings.elements.filter(elm => elm.name.text !== 'PropTypes'); | 
|  | 53 | + | 
|  | 54 | +    if (newNamedBindingElements.length === namedBindings.elements.length) { | 
|  | 55 | +        // Means it has no 'PropTypes' named import | 
|  | 56 | +        return statement; | 
|  | 57 | +    } | 
|  | 58 | + | 
|  | 59 | +    const newImportClause = ts.updateImportClause( | 
|  | 60 | +        statement.importClause, | 
|  | 61 | +        statement.importClause.name, | 
|  | 62 | +        newNamedBindingElements.length === 0 | 
|  | 63 | +            ? undefined | 
|  | 64 | +            : ts.updateNamedImports(namedBindings, newNamedBindingElements), | 
|  | 65 | +    ); | 
|  | 66 | + | 
|  | 67 | +    return ts.updateImportDeclaration( | 
|  | 68 | +        statement, | 
|  | 69 | +        statement.decorators, | 
|  | 70 | +        statement.modifiers, | 
|  | 71 | +        newImportClause, | 
|  | 72 | +        statement.moduleSpecifier, | 
|  | 73 | +    ); | 
|  | 74 | +} | 
0 commit comments