@@ -23,6 +23,12 @@ interface ParserOptions {
23
23
propertyCount : number ;
24
24
depth : number ;
25
25
} ) => 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 ;
26
32
}
27
33
28
34
/**
@@ -61,6 +67,8 @@ export function parseFromProgram(
61
67
program : ts . Program ,
62
68
parserOptions : Partial < ParserOptions > = { } ,
63
69
) {
70
+ const { checkDeclarations = false } = parserOptions ;
71
+
64
72
const shouldInclude : ParserOptions [ 'shouldInclude' ] = data => {
65
73
if ( parserOptions . shouldInclude ) {
66
74
const result = parserOptions . shouldInclude ( data ) ;
@@ -147,12 +155,18 @@ export function parseFromProgram(
147
155
// x = function y(props: type) { return <div/> }
148
156
// x = react.memo((props:type) { return <div/> })
149
157
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 (
156
170
( ts . isArrowFunction ( variableNode . initializer ) ||
157
171
ts . isFunctionExpression ( variableNode . initializer ) ) &&
158
172
variableNode . initializer . parameters . length === 1
0 commit comments