Skip to content

Commit

Permalink
docgen: Fix arrow functions and TS index module support (#30028)
Browse files Browse the repository at this point in the history
* docgen: Detect TS index modules

* docgen: Handle arrow function annotations

* Refactor restParam to explicitly only handle one rest param

* Use more descriptive and singular names for target file cases

* Fix constructor missing return type

* Simplify rest param handling
  • Loading branch information
sarayourfriend authored Apr 5, 2021
1 parent e12881c commit cf2da33
Show file tree
Hide file tree
Showing 5 changed files with 454 additions and 13 deletions.
23 changes: 19 additions & 4 deletions packages/docgen/lib/get-type-annotation.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,22 +12,37 @@ const { types: babelTypes } = require( '@babel/core' );
/* eslint-enable jsdoc/valid-types */

/**
* @param {babelTypes.TSCallSignatureDeclaration | babelTypes.TSFunctionType} typeAnnotation
* @param {babelTypes.TSCallSignatureDeclaration | babelTypes.TSFunctionType | babelTypes.TSConstructSignatureDeclaration} typeAnnotation
* @param {' => ' | ': '} returnIndicator The return indicator to use. Allows using the same function for function annotations and object call properties.
*/
function getFunctionTypeAnnotation( typeAnnotation, returnIndicator ) {
const params = typeAnnotation.parameters
const nonRestParams = typeAnnotation.parameters
.filter( ( p ) => babelTypes.isIdentifier( p ) )
.map(
( p ) =>
`${ p.name }: ${ getTypeAnnotation(
p.typeAnnotation.typeAnnotation
) }`
)
.join( ', ' );

let params = nonRestParams;
const restParam = typeAnnotation.parameters.find(
babelTypes.isRestElement
);
if ( restParam ) {
const paramName = restParam.argument.name;
const paramType = getTypeAnnotation(
restParam.typeAnnotation.typeAnnotation
);
params += `, ...${ paramName }: ${ paramType }`;
}

const returnType = getTypeAnnotation(
typeAnnotation.returnType ||
typeAnnotation.typeAnnotation.typeAnnotation
);

return `( ${ params } )${ returnIndicator }${ returnType }`;
}

Expand Down Expand Up @@ -256,14 +271,14 @@ function getTypeAnnotation( typeAnnotation ) {
return '';
}
case 'TSConstructorType': {
return `new ${ getFunctionTypeAnnotation( typeAnnotation ) }`;
return `new ${ getFunctionTypeAnnotation( typeAnnotation, ': ' ) }`;
}
case 'TSExpressionWithTypeArguments': {
// Unsure with this is
return '';
}
case 'TSFunctionType': {
return getFunctionTypeAnnotation( typeAnnotation );
return getFunctionTypeAnnotation( typeAnnotation, ' => ' );
}
case 'TSImportType': {
return getImportTypeAnnotation( typeAnnotation );
Expand Down
23 changes: 14 additions & 9 deletions packages/docgen/lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,20 +15,25 @@ const isSymbolPrivate = require( './is-symbol-private' );
/**
* Helpers functions.
*/

const extensions = [ '.js', '.ts', '.tsx' ];
const relativeToAbsolute = ( basePath, relativePath ) => {
const target = path.join( path.dirname( basePath ), relativePath );
if ( path.extname( target ) === '.js' ) {
const extension = path.extname( target );
if ( extensions.includes( extension ) ) {
return target;
}
let targetFile = target + '.js';
if ( fs.existsSync( targetFile ) ) {
return targetFile;
}
targetFile = path.join( target, 'index.js' );
if ( fs.existsSync( targetFile ) ) {
return targetFile;

for ( const ext of extensions ) {
const targetFileWithExtension = target + ext;
if ( fs.existsSync( targetFileWithExtension ) ) {
return targetFileWithExtension;
}
const targetFileAsIndexModule = path.join( target, 'index' + ext );
if ( fs.existsSync( targetFileAsIndexModule ) ) {
return targetFileAsIndexModule;
}
}

process.stderr.write( '\nRelative path does not exists.' );
process.stderr.write( '\n' );
process.stderr.write( `\nBase: ${ basePath }` );
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export const fn = (
callback: ( foo: string, ...rest: any[] ) => GenericType< T >
): void => {};
Loading

0 comments on commit cf2da33

Please sign in to comment.