@@ -23,8 +23,8 @@ function isFunctionType(node) {
2323 if ( ! node ) return false ;
2424 const nodeType = node . type ;
2525 return nodeType === 'FunctionDeclaration'
26- || nodeType === 'FunctionExpression'
27- || nodeType === 'ArrowFunctionExpression' ;
26+ || nodeType === 'FunctionExpression'
27+ || nodeType === 'ArrowFunctionExpression' ;
2828}
2929
3030/**
@@ -100,6 +100,7 @@ module.exports = function propTypesInstructions(context, components, utils) {
100100 const defaults = { customValidators : [ ] } ;
101101 const configuration = Object . assign ( { } , defaults , context . options [ 0 ] || { } ) ;
102102 const customValidators = configuration . customValidators ;
103+ const allowedGenericTypes = [ 'React.SFC' , 'React.StatelessComponent' , 'React.FunctionComponent' , 'React.FC' ] ;
103104
104105 /**
105106 * Returns the full scope.
@@ -547,6 +548,11 @@ module.exports = function propTypesInstructions(context, components, utils) {
547548 let typeName ;
548549 if ( astUtil . isTSTypeReference ( node ) ) {
549550 typeName = node . typeName . name ;
551+ if ( ! typeName && node . typeParameters && node . typeParameters . length !== 0 ) {
552+ const nextNode = node . typeParameters . params [ 0 ] ;
553+ this . visitTSNode ( nextNode ) ;
554+ return ;
555+ }
550556 } else if ( astUtil . isTSInterfaceHeritage ( node ) ) {
551557 if ( ! node . expression && node . id ) {
552558 typeName = node . id . name ;
@@ -887,7 +893,15 @@ module.exports = function propTypesInstructions(context, components, utils) {
887893 * FunctionDeclaration, or FunctionExpression
888894 */
889895 function markAnnotatedFunctionArgumentsAsDeclared ( node ) {
890- if ( ! node . params || ! node . params . length || ! annotations . isAnnotatedFunctionPropsDeclaration ( node , context ) ) {
896+ if ( ! node . params || ! node . params . length ) {
897+ return ;
898+ }
899+
900+ const siblingIdentifier = node . parent && node . parent . id ;
901+ const siblingHasTypeAnnotation = siblingIdentifier && siblingIdentifier . typeAnnotation ;
902+ const isNodeAnnotated = annotations . isAnnotatedFunctionPropsDeclaration ( node , context ) ;
903+
904+ if ( ! isNodeAnnotated && ! siblingHasTypeAnnotation ) {
891905 return ;
892906 }
893907
@@ -901,17 +915,38 @@ module.exports = function propTypesInstructions(context, components, utils) {
901915 return ;
902916 }
903917
904- const param = node . params [ 0 ] ;
905- if ( param . typeAnnotation && param . typeAnnotation . typeAnnotation && param . typeAnnotation . typeAnnotation . type === 'UnionTypeAnnotation' ) {
906- param . typeAnnotation . typeAnnotation . types . forEach ( ( annotation ) => {
907- if ( annotation . type === 'GenericTypeAnnotation' ) {
908- markPropTypesAsDeclared ( node , resolveTypeAnnotation ( annotation ) ) ;
909- } else {
910- markPropTypesAsDeclared ( node , annotation ) ;
911- }
912- } ) ;
918+ if ( isNodeAnnotated ) {
919+ const param = node . params [ 0 ] ;
920+ if ( param . typeAnnotation && param . typeAnnotation . typeAnnotation && param . typeAnnotation . typeAnnotation . type === 'UnionTypeAnnotation' ) {
921+ param . typeAnnotation . typeAnnotation . types . forEach ( ( annotation ) => {
922+ if ( annotation . type === 'GenericTypeAnnotation' ) {
923+ markPropTypesAsDeclared ( node , resolveTypeAnnotation ( annotation ) ) ;
924+ } else {
925+ markPropTypesAsDeclared ( node , annotation ) ;
926+ }
927+ } ) ;
928+ } else {
929+ markPropTypesAsDeclared ( node , resolveTypeAnnotation ( param ) ) ;
930+ }
913931 } else {
914- markPropTypesAsDeclared ( node , resolveTypeAnnotation ( param ) ) ;
932+ // implements what's discussed here: https://github.com/yannickcr/eslint-plugin-react/issues/2777#issuecomment-683944481
933+ const annotation = siblingIdentifier . typeAnnotation . typeAnnotation ;
934+
935+ if (
936+ annotation
937+ && annotation . type !== 'TSTypeReference'
938+ && annotation . typeParameters == null
939+ ) {
940+ return ;
941+ }
942+
943+ const typeName = context . getSourceCode ( ) . getText ( annotation . typeName ) . replace ( / / g, '' ) ;
944+
945+ if ( allowedGenericTypes . indexOf ( typeName ) === - 1 ) {
946+ return ;
947+ }
948+
949+ markPropTypesAsDeclared ( node , resolveTypeAnnotation ( siblingIdentifier ) ) ;
915950 }
916951 }
917952
0 commit comments