Skip to content

Commit cbd2eb6

Browse files
committed
feat(parser): check const declarations of React.ComponentType
1 parent 53f1e21 commit cbd2eb6

File tree

1 file changed

+20
-6
lines changed

1 file changed

+20
-6
lines changed

Diff for: src/parser.ts

+20-6
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,12 @@ interface ParserOptions {
2323
propertyCount: number;
2424
depth: number;
2525
}) => boolean | undefined;
26+
/**
27+
* Control if const declarations should be checked
28+
* @default false
29+
* @example declare const Component: React.ComponentType<Props>;
30+
*/
31+
checkDeclarations?: boolean;
2632
}
2733

2834
/**
@@ -61,6 +67,8 @@ export function parseFromProgram(
6167
program: ts.Program,
6268
parserOptions: Partial<ParserOptions> = {},
6369
) {
70+
const { checkDeclarations = false } = parserOptions;
71+
6472
const shouldInclude: ParserOptions['shouldInclude'] = data => {
6573
if (parserOptions.shouldInclude) {
6674
const result = parserOptions.shouldInclude(data);
@@ -147,12 +155,18 @@ export function parseFromProgram(
147155
// x = function y(props: type) { return <div/> }
148156
// x = react.memo((props:type) { return <div/> })
149157

150-
if (
151-
ts.isVariableDeclaration(variableNode) &&
152-
variableNode.name &&
153-
variableNode.initializer
154-
) {
155-
if (
158+
if (ts.isVariableDeclaration(variableNode) && variableNode.name) {
159+
const type = checker.getTypeAtLocation(variableNode.name);
160+
if (!variableNode.initializer) {
161+
if (
162+
checkDeclarations &&
163+
type.aliasSymbol &&
164+
type.aliasTypeArguments &&
165+
checker.getFullyQualifiedName(type.aliasSymbol) === 'React.ComponentType'
166+
) {
167+
parsePropsType(variableNode.name.getText(), type.aliasTypeArguments[0]);
168+
}
169+
} else if (
156170
(ts.isArrowFunction(variableNode.initializer) ||
157171
ts.isFunctionExpression(variableNode.initializer)) &&
158172
variableNode.initializer.parameters.length === 1

0 commit comments

Comments
 (0)