Repository: vercel/next.js
Pull request: [TypeScript Plugin] Match method signature (`someFunc(): void`) type for client boundary warnings

Best to be reviewed with "Hide whitespace".

### Why?

The props marked `(): any` bypassed the warning for non-serializable props.

```tsx
'use client'

export function Comp({ onClick }: { onClick(): any }) {
  // ...
}
```

Added tests to prevent regression.

Changed files:
filename: .changeset/seven-seas-run.md
patch: @@ -0,0 +1,5 @@
+---
+"next": patch
+---
+
+[TypeScript Plugin] Match method signature (`someFunc(): void`) type for client boundary warnings.

filename: packages/next/src/server/typescript/rules/client-boundary.ts
patch: @@ -60,7 +60,11 @@ const clientBoundary = {
                 propTypeInfo.symbol?.getDeclarations()?.[0]
 
               if (typeDeclarationNode) {
-                if (ts.isFunctionTypeNode(typeDeclarationNode)) {
+                if (
+                  ts.isFunctionTypeNode(typeDeclarationNode) ||
+                  // someFunc(): void
+                  ts.isMethodSignature(typeDeclarationNode)
+                ) {
                   // By convention, props named "action" can accept functions since we
                   // assume these are Server Actions. Structurally, there's no
                   // difference between a Server Action and a normal function until

filename: test/development/typescript-plugin/client-boundary/app/non-serializable-action-props.tsx
patch: @@ -5,8 +5,10 @@ class Class {}
 type ArrowFunctionTypeAlias = () => void
 
 export default function ClientComponent(props: {
+  _functionAction(): void
   _arrowFunctionAction: () => void
   _arrowFunctionTypeAliasAction: ArrowFunctionTypeAlias
+  _arrowFunctionConditionalAction: (() => void) | null
   // Doesn't make sense, but check for loophole
   _classAction: Class
   _constructorAction: new () => void

filename: test/development/typescript-plugin/client-boundary/app/non-serializable-props.tsx
patch: @@ -5,8 +5,10 @@ class Class {}
 type ArrowFunctionTypeAlias = () => void
 
 export default function ClientComponent(props: {
+  _function(): void
   _arrowFunction: () => void
   _arrowFunctionTypeAlias: ArrowFunctionTypeAlias
+  _arrowFunctionConditional: (() => void) | null
   _class: Class
   _constructor: new () => void
 }) {

filename: test/development/typescript-plugin/client-boundary/client-boundary.test.ts
patch: @@ -60,13 +60,13 @@ describe('typescript-plugin - client-boundary', () => {
            "code": 71007,
            "length": 5,
            "messageText": "Props must be serializable for components in the "use client" entry file, "_classAction" is invalid.",
-           "start": 276,
+           "start": 357,
          },
          {
            "code": 71007,
            "length": 14,
            "messageText": "Props must be serializable for components in the "use client" entry file, "_constructorAction" is invalid.",
-           "start": 304,
+           "start": 385,
          },
        ],
      }
@@ -93,25 +93,31 @@ describe('typescript-plugin - client-boundary', () => {
            "code": 71007,
            "length": 10,
            "messageText": "Props must be serializable for components in the "use client" entry file. "_arrowFunction" is a function that's not a Server Action. Rename "_arrowFunction" either to "action" or have its name end with "Action" e.g. "_arrowFunctionAction" to indicate it is a Server Action.",
-           "start": 139,
+           "start": 159,
          },
          {
            "code": 71007,
            "length": 22,
            "messageText": "Props must be serializable for components in the "use client" entry file. "_arrowFunctionTypeAlias" is a function that's not a Server Action. Rename "_arrowFunctionTypeAlias" either to "action" or have its name end with "Action" e.g. "_arrowFunctionTypeAliasAction" to indicate it is a Server Action.",
-           "start": 177,
+           "start": 197,
+         },
+         {
+           "code": 71007,
+           "length": 19,
+           "messageText": "Props must be serializable for components in the "use client" entry file. "_arrowFunctionConditional" is a function that's not a Server Action. Rename "_arrowFunctionConditional" either to "action" or have its name end with "Action" e.g. "_arrowFunctionConditionalAction" to indicate it is a Server Action.",
+           "start": 249,
          },
          {
            "code": 71007,
            "length": 5,
            "messageText": "Props must be serializable for components in the "use client" entry file, "_class" is invalid.",
-           "start": 210,
+           "start": 279,
          },
          {
            "code": 71007,
            "length": 14,
            "messageText": "Props must be serializable for components in the "use client" entry file, "_constructor" is invalid.",
-           "start": 232,
+           "start": 301,
          },
        ],
      }