diff --git a/src/typings.ts b/src/typings.ts index 551e7536..403ae848 100644 --- a/src/typings.ts +++ b/src/typings.ts @@ -318,7 +318,7 @@ function getComponentNamesByStaticPropTypeAttribute(ast: AstQuery): string[] { ] `); if (res.length > 0) { - return res.map(match => match.id.name); + return res.map(match => match.id ? match.id.name : ''); } return []; } @@ -337,7 +337,7 @@ function getComponentNamesByJsxInBody(ast: AstQuery): string[] { ] `); if (res.length > 0) { - return res.map(match => match.id.name); + return res.map(match => match.id ? match.id.name : ''); } return []; } @@ -358,6 +358,19 @@ function getPropTypesFromAssignment(ast: AstQuery, componentName: string): any|u } function getPropTypesFromStaticAttribute(ast: AstQuery, componentName: string): any|undefined { + if (componentName === '') { + const res = ast.query(` + //ClassDeclaration + /:body * + //ClassProperty[ + /:key Identifier[@name == 'propTypes'] + ] + /:value* + `); + if (res.length > 0 && !res[0].id) { + return res[0]; + } + } const res = ast.query(` //ClassDeclaration[ /:id Identifier[@name == '${componentName}'] @@ -375,6 +388,19 @@ function getPropTypesFromStaticAttribute(ast: AstQuery, componentName: string): } function getComponentExportType(ast: AstQuery, componentName: string): dom.DeclarationFlags|undefined { + if (componentName === '') { + // case: unnamed default export + const res = ast.query(` + // ExportDefaultDeclaration[ + // ClassDeclaration + || + // FunctionDeclaration + ] + `); + if (res.length > 0 && !res[0].id) { + return dom.DeclarationFlags.ExportDefault; + } + } let res = ast.query(` // ExportDefaultDeclaration[ // ClassDeclaration @@ -424,6 +450,14 @@ function getComponentExportType(ast: AstQuery, componentName: string): dom.Decla function isClassComponent(ast: AstQuery, componentName: string, reactComponentName: string|undefined): boolean { + if (componentName === '') { + const res = ast.query(` + // ClassDeclaration + `); + if (res.length > 0 && !res[0].id) { + return true; + } + } const res = ast.query(` // ClassDeclaration /:id Identifier[@name == '${componentName}'] diff --git a/tests/parsing-test.ts b/tests/parsing-test.ts index 40163b34..41c5e348 100644 --- a/tests/parsing-test.ts +++ b/tests/parsing-test.ts @@ -82,3 +82,6 @@ test('Parsing should create definition from file without propTypes', t => { test('Parsing should create definition from file with references in propTypes', t => { compare(t, 'component', 'references-in-proptypes.jsx', 'references-in-proptypes.d.ts'); }); +test('Parsing should create definition from file with unnamed default export', t => { + compare(t, 'path', 'unnamed-default-export.jsx', 'unnamed-default-export.d.ts'); +}); diff --git a/tests/unnamed-default-export.d.ts b/tests/unnamed-default-export.d.ts new file mode 100644 index 00000000..e1ca5f40 --- /dev/null +++ b/tests/unnamed-default-export.d.ts @@ -0,0 +1,10 @@ +declare module 'path' { + import * as React from 'react'; + + export interface Props { + onClick?: (...args: any[]) => any; + } + + export default class extends React.Component { + } +} diff --git a/tests/unnamed-default-export.jsx b/tests/unnamed-default-export.jsx new file mode 100644 index 00000000..7226f338 --- /dev/null +++ b/tests/unnamed-default-export.jsx @@ -0,0 +1,14 @@ +import {Component, PropTypes} from 'react'; + +export default class extends Component { + + static propTypes = { + onClick: PropTypes.func + }; + + render() { + return ( +
+ ); + } +}