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

Commit 7343af1

Browse files
committed
feat: support generating types for PureComponents
1 parent 8210a62 commit 7343af1

File tree

4 files changed

+50
-11
lines changed

4 files changed

+50
-11
lines changed

src/typings.ts

+21-11
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ export function createTypings(moduleName: string|null, programAst: any, options:
4848
const m = dom.create.module(moduleName || 'moduleName');
4949

5050
if (hasReactClass(ast, reactComponentName)) {
51-
m.members.push(dom.create.importNamed('Component', reactImport));
51+
m.members.push(dom.create.importNamed(reactComponentName || 'Component', reactImport));
5252
} else {
5353
tripleSlashDirectives.push(dom.create.tripleSlashReferenceTypesDirective('react'));
5454
}
@@ -95,19 +95,29 @@ function createExportedTypes(m: dom.ModuleDeclaration, ast: AstQuery, componentN
9595
}
9696

9797
if (classComponent) {
98-
const classDecl = dom.create.class(componentName);
99-
classDecl.baseType = dom.create.interface(`Component<${interf.name}, any>`);
100-
classDecl.flags = exportType;
101-
classDecl.members.push(dom.create.method('render', [], dom.create.namedTypeReference('JSX.Element')));
102-
m.members.push(classDecl);
98+
createExportedClassComponent(m, componentName, reactComponentName, exportType, interf);
10399
} else {
104-
const funcDelc = dom.create.function(componentName, propTypes ? [dom.create.parameter('props', interf)] : [],
105-
dom.create.namedTypeReference('JSX.Element'));
106-
funcDelc.flags = exportType;
107-
m.members.push(funcDelc);
100+
createExportedFunctionalComponent(m, componentName, propTypes, exportType, interf);
108101
}
109102
}
110103

104+
function createExportedClassComponent(m: dom.ModuleDeclaration, componentName: string,
105+
reactComponentName: string|undefined, exportType: dom.DeclarationFlags, interf: dom.InterfaceDeclaration): void {
106+
const classDecl = dom.create.class(componentName);
107+
classDecl.baseType = dom.create.interface(`${reactComponentName || 'Component'}<${interf.name}, any>`);
108+
classDecl.flags = exportType;
109+
classDecl.members.push(dom.create.method('render', [], dom.create.namedTypeReference('JSX.Element')));
110+
m.members.push(classDecl);
111+
}
112+
113+
function createExportedFunctionalComponent(m: dom.ModuleDeclaration, componentName: string, propTypes: any,
114+
exportType: dom.DeclarationFlags, interf: dom.InterfaceDeclaration): void {
115+
const funcDelc = dom.create.function(componentName, propTypes ? [dom.create.parameter('props', interf)] : [],
116+
dom.create.namedTypeReference('JSX.Element'));
117+
funcDelc.flags = exportType;
118+
m.members.push(funcDelc);
119+
}
120+
111121
function createPropTypeTypings(interf: dom.InterfaceDeclaration, ast: AstQuery, propTypes: any,
112122
importedPropTypes: ImportedPropTypes, options: IOptions): void {
113123
const res = ast.querySubtree(propTypes, `
@@ -209,7 +219,7 @@ function getReactComponentName(ast: AstQuery): string|undefined {
209219
/:source StringLiteral[@value == 'react']
210220
]
211221
/:specifiers *[
212-
/ Identifier[@name == 'Component']
222+
/ Identifier[@name == 'Component'] || / Identifier[@name == 'PureComponent']
213223
]
214224
/:local Identifier
215225
`);

tests/parsing-test.ts

+3
Original file line numberDiff line numberDiff line change
@@ -111,3 +111,6 @@ test('Parsing should suppport props-types repo (with a default import)', t => {
111111
test('Parsing should support an SFC with default export babeled to es6', t => {
112112
compare(t, 'component', 'stateless-export-as-default.js', 'stateless-export-as-default.d.ts');
113113
});
114+
test('Parsing should suppport components that extend PureComponent', t => {
115+
compare(t, 'component', 'pure-component.jsx', 'pure-component.d.ts');
116+
});

tests/pure-component.d.ts

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

tests/pure-component.jsx

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import {PureComponent} from 'react';
2+
import * as PropTypes from 'prop-types';
3+
4+
export default class extends PureComponent {
5+
6+
static propTypes = {
7+
optionalString: PropTypes.string
8+
};
9+
10+
render() {
11+
return (
12+
<div></div>
13+
);
14+
}
15+
}

0 commit comments

Comments
 (0)