• Home
  • Writing
  • Resume
  • Home
  • Writing
  • Resume

Writing

  • Why Some Managers Look Disingenuous

    January 3rd, 2024
  • Do’s and Don’ts For Technical Interviews

    December 27th, 2023
  • The Book That Made Me Want To Be A Leader

    October 30th, 2023
  • How to Fail An Interview As the Interviewer

    October 25th, 2023
  • Should Managers Be Prescriptive?

    October 16th, 2023
  • How To Help Unmotivated Developers

    July 12th, 2023
  • What to do when nothing seems good enough

    July 10th, 2023
  • Why Do We Burn Out?

    July 7th, 2023
  • What I Taught You, I Don’t Know

    June 21st, 2023
  • How To Delegate Effectively Without Feeling You Are Losing Control

    June 12th, 2023
  • Let’s Accept It. Technical Interviews Are Broken

    June 7th, 2023
  • Why Managers Need Empathy to Manage Low Performers

    May 31st, 2023
  • The Slow Decline of Highly Motivated Developers

    May 24th, 2023
  • Why Writing Explicit Code Matters

    May 18th, 2023
  • Why Is It So Difficult to Assess Expertise in an Interview?

    May 15th, 2023
  • The Real Value of a Senior Developer When it Comes to Dealing With Uncertainty

    May 11th, 2023
  • Why You Should Use Feature Flags to Deploy with Confidence

    April 28th, 2023
  • Over-Engineering Is Not (Just) a Technical Problem

    March 20th, 2023
  • The proactivity fallacy

    January 25th, 2023
  • Extending typescript intersection with optional properties

    January 18th, 2023
  • Setting up Google Tag Manager in a Nextjs application with a strict content security policy

    December 27th, 2022
  • How to build a scalable folder structure for a nextjs app

    December 11th, 2022
  • Why I have stopped writing comments

    December 6th, 2022
  • How to efficiently type nextjs page's props

    December 6th, 2022

How to efficiently type nextjs page's props

December 6th, 2022

TL;DR;

Use the following line to automatically type your nextjs page props with the returned type of getServerSideProps or getStaticProps

type Props = Awaited<ReturnType<typeof getServerSideProps>>['props']

When working on a nextjs page that receives props from a data fetching method, normally i would type the response of the method and the props the page component receives individually, meaning i would duplicate the type definition, like so

type Props = {
    users: User[]
}

export default function TestFetchers({ users }: Props) {
    return (
        <ul>
            {users.map((user) => (
                <li key={user.name}>{user.name}</li>
            ))}
        </ul>
    )
}

type User = { name: string }

export async function getServerSideProps() {
    const users: User[] = getUsers()

    return {
        props: {
            users,
        },
    }
}

Nothing terribly wrong with that but when you need to add more props, you need to manually modify the Props type, which to me seems like an unnecessary step. After all, we know what getServerSideProps is returning.

Well, you can achieve that with the following line

type Props = Awaited<ReturnType<typeof getServerSideProps>>['props']

Let's break it down

Awaited is one of the typescript utility types and it represents the returned type of a async function. ReturnType is another utility type that, as the name indicates, creates a type from the return type of a function.

Combining both we can create a type that represents the return type of the promise returned by our method getServerSideProps. As the return type of getServerSideProps represents more than just the props key, we just pick that one by using the square brackets notation.

So, that's it. An elegant combination of the utility types allow you to have type-safe props in your page component without having to manually define them. Pretty neat!

Full example

type Props = Awaited<ReturnType<typeof getServerSideProps>>['props']

export default function TestFetchers({ users }: Props) {
    return (
        <ul>
            {users.map((user) => (
                <li key={user.name}>{user.name}</li>
            ))}
        </ul>
    )
}

type User = { name: string }

export async function getServerSideProps() {
    const users: User[] = getUsers()

    return {
        props: {
            users,
        },
    }
}