Next.js: Make GetStaticProps and GetServerSideProps types use generic props

Created on 13 Mar 2020  Â·  7Comments  Â·  Source: vercel/next.js

Feature request

The GetStaticProps and GetServerSideProps typescript types allow us to use the new data fetching methods with typescript, but there is no type check for props content.

Is your feature request related to a problem? Please describe.

The current implementation is as follows:

export type GetStaticProps = (ctx: {
  params?: ParsedUrlQuery
  preview?: boolean
  previewData?: any
}) => Promise<{
  props: { [key: string]: any }
  revalidate?: number | boolean
}>

Describe the solution you'd like

export type GetStaticProps<T = {}> = (ctx: {
  params?: ParsedUrlQuery
  preview?: boolean
  previewData?: any
}) => Promise<{
  props: T
  revalidate?: number | boolean
}>

This way, when defining a Props interface in our page, we can have type safety:

interface Props {
    name: string
}

const Page: NextPage<Props> = (props) => {
    return <div>{props.name}</div>
}

export const getStaticProps: GetStaticProps<Props> = async (context) => {
    const name = await getName(); // string
    return {
        props: {
            name, // yay! Type checked props
        },
    };
};

Something very similar would be implemented for GetServerSideProps.

Describe alternatives you've considered

As the new methods are not static properties of pages anymore, we cannot infer them via the page, so the user may need to add the generic Props type parameter in many places.

Perhaps the types could have more parameters to allow typing previewData?

Most helpful comment

What about types in context params?

in [id].ts

export const getServerSideProps: GetServerSideProps = async (context) => {
    const { id } = context.params;
}

I get this error

Property 'id' does not exist on type 'ParsedUrlQuery | undefined'.
    27 | 
    28 | export const getServerSideProps: GetServerSideProps = async (context) => {
  > 29 |     const { id } = context.params;

In VSCODE
Screenshot_20200325_195818

All 7 comments

Try out next@canary, we already added generics!

What about types in context params?

in [id].ts

export const getServerSideProps: GetServerSideProps = async (context) => {
    const { id } = context.params;
}

I get this error

Property 'id' does not exist on type 'ParsedUrlQuery | undefined'.
    27 | 
    28 | export const getServerSideProps: GetServerSideProps = async (context) => {
  > 29 |     const { id } = context.params;

In VSCODE
Screenshot_20200325_195818

What about types in context params?

in [id].ts

export const getServerSideProps: GetServerSideProps = async (context) => {
    const { id } = context.params;
}

I get this error

Property 'id' does not exist on type 'ParsedUrlQuery | undefined'.
    27 | 
    28 | export const getServerSideProps: GetServerSideProps = async (context) => {
  > 29 |     const { id } = context.params;

In VSCODE
Screenshot_20200325_195818

You got to check first if context.params is not undefined before destructuring this value

For anyone looking for a getStaticProps driven approach instead:

import { GetStaticProps, NextPageContext } from 'next';

export type Await<T> = T extends {
  then(onfulfilled?: (value: infer U) => unknown): unknown;
} ? U : T;

export type ExtractProps<T> = T extends { props: infer P } ? P : never;

export type StaticPageProps<T> = T extends GetStaticProps
  ? ExtractProps<Await<ReturnType<T>>>
  : never;

export type GetStaticPropsContext = Parameters<GetStaticProps>[0];

Then you can have your component read getStaticProps result:

export default function ProductDetailPage(props: StaticPageProps<typeof getStaticProps>) {
  return <>
    // the return type of getPost get's passed
    <h1>{props.post.title}</h1>
   </>;
};

export async function getStaticProps(ctx: GetStaticPropsContext) {
  return {
    post: getPost(ctx)
  }
}

Ok but how to solve it? none of @reaktivo and @elias551 worked for me.

I can't figure it out as well. I've opened up a discussion → https://github.com/vercel/next.js/discussions/16522

Was this page helpful?
0 / 5 - 0 ratings

Related issues

DvirSh picture DvirSh  Â·  3Comments

jesselee34 picture jesselee34  Â·  3Comments

YarivGilad picture YarivGilad  Â·  3Comments

flybayer picture flybayer  Â·  3Comments

sospedra picture sospedra  Â·  3Comments