rsnext/packages/next
Henrik Wenz 3943b20f55
fix: InferGetServerSidePropsType and InferGetStaticPropsType (#40635)
## Problem

Currently the Next.js infer utility (`InferGetServerSidePropsType` and
`InferGetStaticPropsType`) types can lead to a wrong inferred types
(`never`). This happens if these functions return something different
than: `{props: {}}`.

**Example:** `getServerSideProps`

```typescript
export async function getServerSideProps({ query }: GetServerSidePropsContext) {
  if (query.foo) {
    return {
      notFound: true,
    }
  }

  return {
    props: { 
      foo: "bar"
    },
  }
}

type PageProps = InferGetServerSidePropsType<typeof getServerSideProps>
// => type PageProps = never
```

**Example:** `getStaticProps`

```typescript
import type { InferGetStaticPropsType, GetStaticPropsContext } from 'next'

export async function getStaticProps(context: GetStaticPropsContext) {
  if (context.params?.bar) {
    return {
      notFound: true,
    }
  }

  return {
    props: {
      foo: 'bar',
    },
  }
}

type PageProps = InferGetStaticPropsType<typeof getStaticProps>
// => type PageProps = never
```

This is because the first infer condition of the utility type is not
satified leading to a never result.

```typescript
export type InferGetServerSidePropsType<T> = T extends GetServerSideProps<
  infer P, // <- NOT SATISFIED
  any
>
  ? P
  : T extends (
      context?: GetServerSidePropsContext<any>
    ) => Promise<GetServerSidePropsResult<infer P>>
  ? P
  : never  // <- NOT SATISFIED
```

## Solution

I have experimented with different solutions ending with a much simpler
type, that is faster to execute, easier to read and universally usable
for both prop variations.

```typescript
/**
 * Flow:
 * - Make sure getStaticProps is a function
 * - Get its return type
 * - Extract the one that contains {props: any}
 * - Return the props
 */
export type InferGetStaticPropsType<T extends (args: any) => any> = Extract<
  Awaited<ReturnType<T>>,
  { props: any }
>['props']
```

## Bug

- [x] Related issues: fixes #36615, #15913,
https://twitter.com/leeerob/status/1563540593003106306
- [x] Type tests added

## Future thoughts

Since `InferGetStaticPropsType` and `InferGetServerSidePropsType` are
now the same, it's api could be merged into one utility type (e.g:
InferNextProps). I recommend doing this in a different PR.

## Additional info

I have tested this approach using the following [external
package](https://www.npmjs.com/package/infer-next-props-type)
(@timneutkens sorry for the late PR). Since about 12 Month I haven't
received any negative feedback (issues) regarding this approach.

Co-authored-by: JJ Kasper <jj@jjsweb.site>
2022-09-20 15:25:01 -07:00
..
bin fix(next): dev server starting when importing a file using get-projec… (#38274) 2022-08-07 17:31:30 +00:00
build Use resolved url in flight entry loader (#40697) 2022-09-20 10:40:27 +00:00
bundles refactor: split up CONTRIBUTING.md (#40515) 2022-09-16 14:54:58 -07:00
cli Bypass empty pages folder for layouts (#40132) 2022-09-03 00:13:47 +00:00
client Combine redirect function in new router (#40717) 2022-09-20 16:55:10 +02:00
compiled Upgrade to latest React experimental (#40672) 2022-09-19 13:26:06 +00:00
export Add handling for static generation in app (#40561) 2022-09-19 18:05:28 +00:00
future Add experimental next/future/image component (#37927) 2022-06-24 14:56:05 +00:00
image-types Don't import internally from types in next-env.d.ts (#34394) 2022-02-19 04:25:49 +01:00
lib Implement SWC transformer for server and client graphs (#40603) 2022-09-17 00:12:59 +02:00
pages Avoid direct React client API imports in the server graph (#40686) 2022-09-19 20:08:52 +02:00
server Handle redirects in new router (#40396) 2022-09-20 15:28:07 +02:00
shared/lib Handle redirects in new router (#40396) 2022-09-20 15:28:07 +02:00
telemetry Update to stable: next/future/image, remotePatterns, unoptimized (#40142) 2022-08-31 22:44:17 +00:00
trace Small code improvements (#37227) 2022-05-26 23:19:47 +00:00
types fix: InferGetServerSidePropsType and InferGetStaticPropsType (#40635) 2022-09-20 15:25:01 -07:00
amp.d.ts
amp.js
app.d.ts
app.js
babel.d.ts
babel.js
client.d.ts
client.js
config.d.ts
config.js
constants.d.ts
constants.js
document.d.ts
document.js
dynamic.d.ts
dynamic.js
error.d.ts
error.js
head.d.ts
head.js fix(#36435): apply correct fix (#36464) 2022-04-26 11:15:49 -05:00
image.d.ts
image.js
index.d.ts typing: upgrade styled-jsx to remove workaround in build script (#39408) 2022-08-09 17:10:33 +00:00
jest.d.ts
jest.js fix(#36534): enable interopClientDefaultExport for next/jest (#36824) 2022-05-11 13:13:13 -05:00
license.md
link.d.ts
link.js
package.json v12.3.1 2022-09-19 15:41:52 -07:00
README.md docs(README): next.js logo with dark mode (#40223) 2022-09-13 16:39:52 +02:00
router.d.ts
router.js
script.d.ts
script.js
server.d.ts Export URLPattern from next/server (#39219) 2022-08-02 02:04:08 +00:00
server.js refactor: add named export in next/server (#39381) 2022-08-07 16:17:15 +00:00
taskfile-ncc.js
taskfile-swc.js Client directive (#40415) 2022-09-18 00:00:16 +00:00
taskfile.js Implement SWC transformer for server and client graphs (#40603) 2022-09-17 00:12:59 +02:00
tsconfig.json Remove webpack4 types (#39631) 2022-08-16 09:55:37 +00:00

Next.js

Getting Started

Visit https://nextjs.org/learn to get started with Next.js.

Documentation

Visit https://nextjs.org/docs to view the full documentation.

Who is using Next.js?

Next.js is used by the world's leading companies. Check out the Next.js Showcase to learn more.

Community

The Next.js community can be found on GitHub Discussions, where you can ask questions, voice ideas, and share your projects.

To chat with other community members you can join the Next.js Discord.

Our Code of Conduct applies to all Next.js community channels.

Contributing

Please see our contributing.md.

Good First Issues

We have a list of good first issues that contain bugs that have a relatively limited scope. This is a great place to get started, gain experience, and get familiar with our contribution process.

Authors

Security

If you believe you have found a security vulnerability in Next.js, we encourage you to responsibly disclose this and not open a public issue. We will investigate all legitimate reports. Email security@vercel.com to disclose any security vulnerabilities.

https://vercel.com/security