import { PluginPass } from '@babel/core' ; import { ArrowFunctionExpression , ClassMethod , FunctionDeclaration , FunctionExpression , FunctionTypeAnnotation , FunctionTypeParam , Identifier , RestElement , TSFunctionType , identifier , isAssignmentPattern , isIdentifier , restElement , tsFunctionType , tsTypeAnnotation , } from '@babel/types' ; import { convertFlowType } from './flow-type' ; import { convertTypeParameterDeclaration } from './type-parameter' ; import { convertTypeAnnotation } from './type-annotation' ; function functionTypeParamToIdentifier ( param , fallbackName , state ) { const id = identifier ( isIdentifier ( param . name ) ? param . name . name : fallbackName ) ; id . optional = param . optional ; id . typeAnnotation = convertTypeAnnotation ( param , state ) ; return id ; } export function functionTypeParametersToIdentifiers ( params , state ) { if ( params === null ) { return null ; } return params . map ( ( param , i ) => { return functionTypeParamToIdentifier ( param , params . length > 1 ? `p${ i + 1 }` : `p` , state ) ; } ) ; } export function convertFunctionTypeRestParam ( param , state ) { const id = identifier ( isIdentifier ( param . name ) ? param . name . name : 'rest' ) ; const restElem = restElement ( id ) ; restElem . typeAnnotation = convertTypeAnnotation ( param , state ) ; return restElem ; } export function convertFunctionTypeAnnotation ( node , state ) { const typeParameters = convertTypeParameterDeclaration ( node . typeParameters , state ) ; const functionParameters = functionTypeParametersToIdentifiers ( node . params , state ) || [ ] ; const restParameters = node . rest ? [ convertFunctionTypeRestParam ( node . rest , state ) ] : [ ] ; const returnType = tsTypeAnnotation ( convertFlowType ( node . returnType , state ) ) ; return tsFunctionType ( typeParameters , [ ... functionParameters , ... restParameters ] , returnType ) ; } export function convertOptionalFunctionParameters < Fn extends ArrowFunctionExpression | ClassMethod | FunctionDeclaration | FunctionExpression > ( node ) { node . params = node . params . map ( param => { if ( isAssignmentPattern ( param ) && isIdentifier ( param . left ) && param . left . optional ) { param . left . optional = false ; } return param ; } ) ; return node ; }