Skip to content
This repository was archived by the owner on Nov 27, 2023. It is now read-only.

Commit da9863b

Browse files
committed
feat: resolve referenced propTypes
1 parent c1a0618 commit da9863b

File tree

4 files changed

+52
-2
lines changed

4 files changed

+52
-2
lines changed

Diff for: src/typings.ts

+27-2
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,7 @@ export function createTypings(moduleName: string|null, programAst: any, options:
4747
}
4848
componentNames.forEach(componentName => {
4949
const exportType = getComponentExportType(ast, componentName);
50-
const propTypes = getPropTypesFromAssignment(ast, componentName) ||
51-
getPropTypesFromStaticAttribute(ast, componentName);
50+
const propTypes = getPropTypes(ast, componentName);
5251
if (exportType) {
5352
createExportedTypes(m, ast, componentName, reactComponentName, propTypes, propTypesName, exportType, options);
5453
}
@@ -344,6 +343,18 @@ function getComponentNamesByJsxInBody(ast: AstQuery): string[] {
344343
return [];
345344
}
346345

346+
function getPropTypes(ast: AstQuery, componentName: string): any|undefined {
347+
const propTypes = getPropTypesFromAssignment(ast, componentName) ||
348+
getPropTypesFromStaticAttribute(ast, componentName);
349+
350+
const referencedComponentName = getReferencedPropTypesComponentName(ast, propTypes);
351+
if (referencedComponentName) {
352+
return getPropTypes(ast, referencedComponentName);
353+
}
354+
355+
return propTypes;
356+
}
357+
347358
function getPropTypesFromAssignment(ast: AstQuery, componentName: string): any|undefined {
348359
const res = ast.query(`
349360
//AssignmentExpression[
@@ -389,6 +400,20 @@ function getPropTypesFromStaticAttribute(ast: AstQuery, componentName: string):
389400
return undefined;
390401
}
391402

403+
function getReferencedPropTypesComponentName(ast: AstQuery, propTypes: any|undefined): string|undefined {
404+
if (propTypes) {
405+
const propTypesReference = ast.querySubtree(propTypes, `
406+
MemberExpression [
407+
/:property Identifier[@name == 'propTypes']
408+
] /:object Identifier
409+
`);
410+
if (propTypesReference.length > 0) {
411+
return propTypesReference[0].name;
412+
}
413+
}
414+
return undefined;
415+
}
416+
392417
function getComponentExportType(ast: AstQuery, componentName: string): dom.DeclarationFlags|undefined {
393418
if (componentName === '') {
394419
// case: unnamed default export

Diff for: tests/parsing-test.ts

+3
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,9 @@ test('Parsing should create definition from file without propTypes', t => {
8484
test('Parsing should create definition from file with references in propTypes', t => {
8585
compare(t, 'component', 'references-in-proptypes.jsx', 'references-in-proptypes.d.ts');
8686
});
87+
test('Parsing should create definition from file with reference as propTypes', t => {
88+
compare(t, 'component', 'reference-as-proptypes.jsx', 'reference-as-proptypes.d.ts');
89+
});
8790
test('Parsing should create definition from file with unnamed default export', t => {
8891
compare(t, 'path', 'unnamed-default-export.jsx', 'unnamed-default-export.d.ts');
8992
});

Diff for: tests/reference-as-proptypes.d.ts

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
declare module 'component' {
2+
import {Component} from 'react';
3+
4+
export interface SomeComponentProps {
5+
someString?: string;
6+
}
7+
8+
export default class SomeComponent extends Component<SomeComponentProps, any> {
9+
render(): JSX.Element;
10+
}
11+
}

Diff for: tests/reference-as-proptypes.jsx

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import React from 'react';
2+
3+
class SomeInternalComponent extends React.Component {
4+
static propTypes = {
5+
someString: React.PropTypes.string
6+
};
7+
}
8+
9+
export default class SomeComponent extends React.Component {
10+
static propTypes = SomeInternalComponent.propTypes;
11+
}

0 commit comments

Comments
 (0)