Skip to content

Commit

Permalink
Improve error message for wrong props (#41668)
Browse files Browse the repository at this point in the history
This PR improves the type checking error message when you have unnecessary props:

```tsx
export default function Page({ whatIsThis }) {
  return <div>hello</div>
}
```

![CleanShot 2022-10-22 at 17 14 38@2x](https://user-images.githubusercontent.com/3676859/197367064-3aac325e-8756-4295-898c-adc52453d088.png)

## Bug

- [ ] Related issues linked using `fixes #number`
- [ ] Integration tests added
- [ ] Errors have a helpful link attached, see `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`
- [ ] Integration 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`

## Documentation / Examples

- [ ] Make sure the linting passes by running `pnpm lint`
- [ ] The "examples guidelines" are followed from [our contributing doc](https://github.com/vercel/next.js/blob/canary/contributing/examples/adding-examples.md)
  • Loading branch information
shuding committed Oct 23, 2022
1 parent b0f87fb commit aca3e98
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 9 deletions.
11 changes: 9 additions & 2 deletions packages/next/build/webpack/plugins/flight-types-plugin.ts
Expand Up @@ -25,13 +25,20 @@ type TEntry = typeof entry
check<IEntry, TEntry>(entry)
type PageProps = { params?: any }
type LayoutProps = { children: React.ReactNode; params?: any }
type PageComponent = (props: PageProps) => React.ReactNode | null
type LayoutComponent = (props: LayoutProps) => React.ReactNode | null
interface IEntry {
${
options.type === 'layout'
? `default: (props: { children: React.ReactNode; params?: any }) => React.ReactNode | null`
: `default: (props: { params?: any }) => React.ReactNode | null`
? `default: LayoutComponent`
: `default: PageComponent`
}
config?: {}
Head?: any
generateStaticParams?: (params?:any) => Promise<any[]>
revalidate?: RevalidateRange<TEntry> | false
dynamic?: 'auto' | 'force-dynamic' | 'error' | 'force-static'
Expand Down
30 changes: 24 additions & 6 deletions packages/next/lib/typescript/diagnosticFormatter.ts
Expand Up @@ -61,12 +61,19 @@ function getFormattedLayoutAndPageDiagnosticMessageText(
)
if (types) {
main += '\n' + ' '.repeat(indent * 2)
main += `Expected "${chalk.bold(
types[2].replace(
'"__invalid_negative_number__"',
'number (>= 0)'
)
)}", got "${chalk.bold(types[1])}".`

if (types[2] === 'PageComponent') {
main += `The exported page component isn't correctly typed.`
} else if (types[2] === 'LayoutComponent') {
main += `The exported layout component isn't correctly typed.`
} else {
main += `Expected "${chalk.bold(
types[2].replace(
'"__invalid_negative_number__"',
'number (>= 0)'
)
)}", got "${chalk.bold(types[1])}".`
}
}
break
case 2326:
Expand All @@ -80,6 +87,17 @@ function getFormattedLayoutAndPageDiagnosticMessageText(
main += `Type "${chalk.bold(invalid[1])}" isn't allowed.`
}
break
case 2741:
const incompatProp = item.messageText.match(
/Property '(.+)' is missing in type 'PageProps'/
)
if (incompatProp) {
main += '\n' + ' '.repeat(indent * 2)
main += `Prop "${chalk.bold(
incompatProp[1]
)}" will never be passed. Remove it from the component's props.`
}
break
default:
}

Expand Down
2 changes: 1 addition & 1 deletion test/e2e/app-dir/app-typescript/app/inner/page.tsx
Expand Up @@ -4,7 +4,7 @@

import { useCallback, useState } from 'react'

export default function Page() {
export default function Page({ whatIsThis }) {
return <div>hello</div>
}

Expand Down

0 comments on commit aca3e98

Please sign in to comment.