Skip to content

Commit d16d9f4

Browse files
[TypeScript Plugin] Match method signature (someFunc(): void) type for client boundary warnings (#79144)
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. --------- Co-authored-by: Janka Uryga <lolzatu2@gmail.com>
1 parent d9fdecf commit d16d9f4

File tree

5 files changed

+26
-7
lines changed

5 files changed

+26
-7
lines changed

.changeset/seven-seas-run.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"next": patch
3+
---
4+
5+
[TypeScript Plugin] Match method signature (`someFunc(): void`) type for client boundary warnings.

packages/next/src/server/typescript/rules/client-boundary.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,11 @@ const clientBoundary = {
6060
propTypeInfo.symbol?.getDeclarations()?.[0]
6161

6262
if (typeDeclarationNode) {
63-
if (ts.isFunctionTypeNode(typeDeclarationNode)) {
63+
if (
64+
ts.isFunctionTypeNode(typeDeclarationNode) ||
65+
// someFunc(): void
66+
ts.isMethodSignature(typeDeclarationNode)
67+
) {
6468
// By convention, props named "action" can accept functions since we
6569
// assume these are Server Actions. Structurally, there's no
6670
// difference between a Server Action and a normal function until

test/development/typescript-plugin/client-boundary/app/non-serializable-action-props.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,10 @@ class Class {}
55
type ArrowFunctionTypeAlias = () => void
66

77
export default function ClientComponent(props: {
8+
_functionAction(): void
89
_arrowFunctionAction: () => void
910
_arrowFunctionTypeAliasAction: ArrowFunctionTypeAlias
11+
_arrowFunctionConditionalAction: (() => void) | null
1012
// Doesn't make sense, but check for loophole
1113
_classAction: Class
1214
_constructorAction: new () => void

test/development/typescript-plugin/client-boundary/app/non-serializable-props.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,10 @@ class Class {}
55
type ArrowFunctionTypeAlias = () => void
66

77
export default function ClientComponent(props: {
8+
_function(): void
89
_arrowFunction: () => void
910
_arrowFunctionTypeAlias: ArrowFunctionTypeAlias
11+
_arrowFunctionConditional: (() => void) | null
1012
_class: Class
1113
_constructor: new () => void
1214
}) {

test/development/typescript-plugin/client-boundary/client-boundary.test.ts

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -60,13 +60,13 @@ describe('typescript-plugin - client-boundary', () => {
6060
"code": 71007,
6161
"length": 5,
6262
"messageText": "Props must be serializable for components in the "use client" entry file, "_classAction" is invalid.",
63-
"start": 276,
63+
"start": 357,
6464
},
6565
{
6666
"code": 71007,
6767
"length": 14,
6868
"messageText": "Props must be serializable for components in the "use client" entry file, "_constructorAction" is invalid.",
69-
"start": 304,
69+
"start": 385,
7070
},
7171
],
7272
}
@@ -93,25 +93,31 @@ describe('typescript-plugin - client-boundary', () => {
9393
"code": 71007,
9494
"length": 10,
9595
"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.",
96-
"start": 139,
96+
"start": 159,
9797
},
9898
{
9999
"code": 71007,
100100
"length": 22,
101101
"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.",
102-
"start": 177,
102+
"start": 197,
103+
},
104+
{
105+
"code": 71007,
106+
"length": 19,
107+
"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.",
108+
"start": 249,
103109
},
104110
{
105111
"code": 71007,
106112
"length": 5,
107113
"messageText": "Props must be serializable for components in the "use client" entry file, "_class" is invalid.",
108-
"start": 210,
114+
"start": 279,
109115
},
110116
{
111117
"code": 71007,
112118
"length": 14,
113119
"messageText": "Props must be serializable for components in the "use client" entry file, "_constructor" is invalid.",
114-
"start": 232,
120+
"start": 301,
115121
},
116122
],
117123
}

0 commit comments

Comments
 (0)