Home > Back-end >  Typescript shaping: What is the meaning of each section of this Next.js component?
Typescript shaping: What is the meaning of each section of this Next.js component?

Time:01-23

Let's take this function, for example:

interface IParams extends ParsedUrlQuery {
    id: string
}

interface Props {
  params: {
    id: string;
  };
}

export const getStaticProps: GetStaticProps<IParams> = async ({ params: { id } }: Props) => {
  const { data: lesson } = await supabase
    .from("lesson")
    .select("*")
    .eq("id", id)
    .single();

  return {
    props: {
      lesson,
    },
  };
};

When we review this signature:

export const getStaticProps: GetStaticProps<IParams> = async ({ params: { id } }: Props) => { ... }

What is the first <IParams> shape defining? Is this the input of the getStaticProps function, or its output?

If I have <IParams> specified, do I need the "Props" shape?

What defines the shape of the output using this example?

CodePudding user response:

Let's start with GetStaticProps<FirstShape, SecondShape> and the dynamic page [id].js.

The first shape is the return type of getStaticProps, which should also match the prop type for the page.

The second shape is the query params for getStaticProps.


Since the query param is id (defined by the file name) will be passed in query params. However, it could also be undefined, so you must account for that.

[id].js

import { GetStaticProps } from "next";
import { FC } from "react";

type PageProps = {
  yourData: any;
};

type QueryParams = {
  id: string;
};

const Page: FC<PageProps> = ({ yourData }) => {
  console.log(yourData);
  return <div>Page</div>;
};

export const getStaticProps: GetStaticProps<PageProps, QueryParams> = ({ params }) => {
  if(!params || params.id) {
    return { notFound: true };
  }
  return {
    props: {
      yourData: { id: params.id },
    },
  };
};

export default Page;

Based on your example, you'd have something like...

import { GetStaticProps } from "next";
import { FC } from "react";

type PageProps = {
  lesson: any // your lesson type
};

type QueryParams = {
  id: string;
};

const Page: FC<PageProps> = ({ lesson }) => {
  console.log(lesson);
  return <div>Page</div>;
};

export const getStaticProps: GetStaticProps<PageProps, QueryParams> = async ({
  params, // possibly undefined, don't destructure here
}) => {
  try {
    if (!params || params.id) throw Error("No id"); // throw error, so it goes to the catch statement to return notFound
    const { id } = params; // destructure after you know params is defined
    const { data, error } = await supabase.from("lesson").select("*").eq("id", id).single();
    if (!data || error) throw Error(error.message ?? "No data");
    return { props: { lesson: data } };
  } catch (e) {
    console.error(e);
    return { notFound: true };
  }
};

export default Page;
  • Related