-
Notifications
You must be signed in to change notification settings - Fork 27.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
InferGetServerSidePropsType doesn't work with conditional returns #36615
Comments
You have to use |
@GabenGar I just switched getServerSideProps to:
and |
Let's say you have |
I think I attempted what you mentioned, but no luck still. I also went back to the docs: and I couldn't find a similar example either. I'm still new to TypeScript, perhaps you could copy/paste my example with the changes? |
I have a page which uses it. |
That worked, thank you @GabenGar! Here it is completely, so people can reference it in the future:
My mistake was that I did this:
@GabenGar, aren't we returning an object with everything inside a props object? Why does including that in the interface not work? I'm confused about that. |
Because the generic for |
Thanks @GabenGar, that makes sense. I appreciate the help! @balazsorban44, could this ticket track making the documentation here more clear? I'm not a TypeScript expert, but I could imagine others getting confused by it as well. |
@balazsorban44 bumping this issue |
@anthonyalayo you're absolute right! I was so confused on why this did not work. Updating the documentation would certainly help other people. |
## 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 <[email protected]>
This closed issue has been automatically locked because it had no new activity for a month. If you are running into a similar issue, please create a new issue with the steps to reproduce. Thank you. |
Verify canary release
Provide environment information
❯ next info
What browser are you using? (if relevant)
No response
How are you deploying your application? (if relevant)
No response
Describe the Bug
In the documentation here: https://nextjs.org/docs/api-reference/data-fetching/get-server-side-props#redirect
We are shown that we can return a redirect or a notFound instead of props. I have attempted to do that in TypeScript here:
If there is logic handling a conditional redirect, we don't get type inference. Here is a WebStorm screenshot showing that:
Once I remove the conditional logic:
Then type inference works again:
Expected Behavior
Type inference works with conditionals.
To Reproduce
One way of reproducing is copy/pasting what I provided in the bug description:
This however requires extra dependencies to be installed. With no dependencies, you can simply take the example from the docs and attempt to use type inference with it: https://nextjs.org/docs/api-reference/data-fetching/get-server-side-props#redirect
The text was updated successfully, but these errors were encountered: