@@ -651,24 +651,75 @@ function isMemoCallback(path: NodePath<t.Expression>): boolean {
651651 ) ;
652652}
653653
654+ function isValidPropsAnnotation (
655+ annot : t . TypeAnnotation | t . TSTypeAnnotation | t . Noop | null | undefined
656+ ) : boolean {
657+ if ( annot == null ) {
658+ return true ;
659+ } else if ( annot . type === "TSTypeAnnotation" ) {
660+ switch ( annot . typeAnnotation . type ) {
661+ case "TSArrayType" :
662+ case "TSBigIntKeyword" :
663+ case "TSBooleanKeyword" :
664+ case "TSConstructorType" :
665+ case "TSFunctionType" :
666+ case "TSLiteralType" :
667+ case "TSNeverKeyword" :
668+ case "TSNumberKeyword" :
669+ case "TSStringKeyword" :
670+ case "TSSymbolKeyword" :
671+ case "TSTupleType" :
672+ return false ;
673+ }
674+ return true ;
675+ } else if ( annot . type === "TypeAnnotation" ) {
676+ switch ( annot . typeAnnotation . type ) {
677+ case "ArrayTypeAnnotation" :
678+ case "BooleanLiteralTypeAnnotation" :
679+ case "BooleanTypeAnnotation" :
680+ case "EmptyTypeAnnotation" :
681+ case "FunctionTypeAnnotation" :
682+ case "NumberLiteralTypeAnnotation" :
683+ case "NumberTypeAnnotation" :
684+ case "StringLiteralTypeAnnotation" :
685+ case "StringTypeAnnotation" :
686+ case "SymbolTypeAnnotation" :
687+ case "ThisTypeAnnotation" :
688+ case "TupleTypeAnnotation" :
689+ return false ;
690+ }
691+ return true ;
692+ } else if ( annot . type === "Noop" ) {
693+ return true ;
694+ } else {
695+ assertExhaustive ( annot , `Unexpected annotation node \`${ annot } \`` ) ;
696+ }
697+ }
698+
654699function isValidComponentParams (
655700 params : Array < NodePath < t . Identifier | t . Pattern | t . RestElement > >
656701) : boolean {
657702 if ( params . length === 0 ) {
658703 return true ;
659- } else if ( params . length === 1 ) {
660- return ! params [ 0 ] . isRestElement ( ) ;
661- } else if ( params . length === 2 ) {
662- // check if second param might be a ref
663- if ( params [ 1 ] . isIdentifier ( ) ) {
704+ } else if ( params . length > 0 && params . length <= 2 ) {
705+ if ( ! isValidPropsAnnotation ( params [ 0 ] . node . typeAnnotation ) ) {
706+ return false ;
707+ }
708+
709+ if ( params . length === 1 ) {
710+ return ! params [ 0 ] . isRestElement ( ) ;
711+ } else if ( params [ 1 ] . isIdentifier ( ) ) {
712+ // check if second param might be a ref
664713 const { name } = params [ 1 ] . node ;
665714 return name . includes ( "ref" ) || name . includes ( "Ref" ) ;
715+ } else {
716+ /**
717+ * Otherwise, avoid helper functions that take more than one argument.
718+ * Helpers are _usually_ named with lowercase, but some code may
719+ * violate this rule
720+ */
721+ return false ;
666722 }
667- /**
668- * Otherwise, avoid helper functions that take more than one argument.
669- * Helpers are _usually_ named with lowercase, but some code may
670- * violate this rule
671- */
672723 }
673724 return false ;
674725}
0 commit comments