Skip to content

Commit

Permalink
Show error for invalid page props in the TS plugin (#43300)
Browse files Browse the repository at this point in the history
For page entries, currently it's only allowed to have `params` and
`searchParams` in props:

<img width="677" alt="CleanShot 2022-11-23 at 16 18 57@2x"
src="https://user-images.githubusercontent.com/3676859/203583323-12c24900-8046-4b3b-ac95-b0ed1bee37e4.png">

In the future, this will cover more cases for layout entries too.

## Bug

- [ ] Related issues linked using `fixes #number`
- [ ] Integration tests added
- [ ] Errors have a helpful link attached, see
[`contributing.md`](https://github.com/vercel/next.js/blob/canary/contributing.md)

## Feature

- [ ] Implements an existing feature request or RFC. Make sure the
feature request has been accepted for implementation before opening a
PR.
- [ ] Related issues linked using `fixes #number`
- [ ]
[e2e](https://github.com/vercel/next.js/blob/canary/contributing/core/testing.md#writing-tests-for-nextjs)
tests added
- [ ] Documentation added
- [ ] Telemetry added. In case of a feature if it's used or not.
- [ ] Errors have a helpful link attached, see
[`contributing.md`](https://github.com/vercel/next.js/blob/canary/contributing.md)

## Documentation / Examples

- [ ] Make sure the linting passes by running `pnpm build && pnpm lint`
- [ ] The "examples guidelines" are followed from [our contributing
doc](https://github.com/vercel/next.js/blob/canary/contributing/examples/adding-examples.md)

Co-authored-by: Jiachi Liu <inbox@huozhi.im>
  • Loading branch information
shuding and huozhi committed Nov 23, 2022
1 parent 2089af4 commit 685c87c
Showing 1 changed file with 48 additions and 1 deletion.
49 changes: 48 additions & 1 deletion packages/next/server/next-typescript.ts
Expand Up @@ -29,11 +29,14 @@ const DISALLOWED_SERVER_REACT_APIS: string[] = [

const ALLOWED_EXPORTS = ['config', 'generateStaticParams']

const ALLOWED_PAGE_PROPS = ['params', 'searchParams']

const NEXT_TS_ERRORS = {
INVALID_SERVER_API: 71001,
INVALID_ENTRY_EXPORT: 71002,
INVALID_OPTION_VALUE: 71003,
MISPLACED_CLIENT_ENTRY: 71004,
INVALID_PAGE_PROP: 71005,
}

const API_DOCS: Record<
Expand Down Expand Up @@ -197,7 +200,13 @@ export function createTSPlugin(modules: {
const isAppEntryFile = (filePath: string) => {
return (
filePath.startsWith(appDir) &&
/(page|layout)\.(mjs|js|jsx|ts|tsx)$/.test(path.basename(filePath))
/^(page|layout)\.(mjs|js|jsx|ts|tsx)$/.test(path.basename(filePath))
)
}
const isPageFile = (filePath: string) => {
return (
filePath.startsWith(appDir) &&
/^page\.(mjs|js|jsx|ts|tsx)$/.test(path.basename(filePath))
)
}

Expand Down Expand Up @@ -666,6 +675,44 @@ export function createTSPlugin(modules: {
}
}
}
} else if (ts.isFunctionDeclaration(node)) {
let hasExportKeyword = false
let hasDefaultKeyword = false

if (node.modifiers) {
for (const modifier of node.modifiers) {
if (modifier.kind === ts.SyntaxKind.ExportKeyword) {
hasExportKeyword = true
} else if (modifier.kind === ts.SyntaxKind.DefaultKeyword) {
hasDefaultKeyword = true
}
}
}

// `export default function`
if (hasExportKeyword && hasDefaultKeyword) {
if (isPageFile(fileName)) {
const props = node.parameters?.[0]?.name
// For page entries (page.js), it can only have `params` and `searchParams`
// as the prop names.
if (props && ts.isObjectBindingPattern(props)) {
for (const prop of (props as ts.ObjectBindingPattern)
.elements) {
const propName = prop.name.getText()
if (!ALLOWED_PAGE_PROPS.includes(propName)) {
prior.push({
file: source,
category: ts.DiagnosticCategory.Error,
code: NEXT_TS_ERRORS.INVALID_PAGE_PROP,
messageText: `"${propName}" is not a valid page property.`,
start: prop.getStart(),
length: prop.getWidth(),
})
}
}
}
}
}
}
})
}
Expand Down

0 comments on commit 685c87c

Please sign in to comment.