kob003
kob003

Reputation: 3717

How to correctly assign types of props in next js while using typescript?

This is my index.tsx file:

    import type { NextPage } from "next";
    
    type AppProps = {
      articles: {
        userId: number;
        id: number;
        title: string;
        body: string;
      };
    };
    
    const Home: NextPage = ({articles}:AppProps) => {
      return (
        <div>
          <h1>Welcome to {articles.title}</h1>
        </div>
      );
    };

    export const getStaticProps = async () => {
    const res = await fetch('https://jsonplaceholder.typicode.com/posts/1')
    const articles = await res.json();
    
      return {
        props: { articles },
      };
    };
 export default Home;

The code did get rendered but there is an error in my Home component. It shows the following error message:

Type '({ articles }: AppProps) => JSX.Element' is not assignable to type 'NextPage<{}, {}>'.
  Type '({ articles }: AppProps) => JSX.Element' is not assignable to type 'FunctionComponent<{}> & { getInitialProps?(context: NextPageContext): {} | Promise<{}>; }'.
    Type '({ articles }: AppProps) => JSX.Element' is not assignable to type 'FunctionComponent<{}>'.
      Types of parameters '__0' and 'props' are incompatible.
        Property 'articles' is missing in type '{}' but required in type 'AppProps'.

Is there anything i am doing wrong? I could not figure it out. Please help.

Upvotes: 2

Views: 5521

Answers (2)

pureth
pureth

Reputation: 828

You can use InferGetStaticPropsType or InferGetServerSidePropsType as needed.

Using your example:

    import type { InferGetStaticPropsType } from "next";
    
    type Article = {
      userId: number;
      id: number;
      title: string;
      body: string;
    };
    
    const Home = ({articles}: InferGetStaticPropsType<typeof getStaticProps>) => {
      return (
        <div>
          <h1>Welcome to {articles.title}</h1>
        </div>
      );
    };

    export const getStaticProps = async () => {
    const res = await fetch('https://jsonplaceholder.typicode.com/posts/1')
    const articles: Article[] = await res.json();
    
      return {
        props: { articles },
      };
    };
 export default Home;

Upvotes: 0

Mark G
Mark G

Reputation: 2196

NextPage is based on NextComponentType which has a type parameter list with default values ({}) for initial page data (props):

// With no type arguments passed in, `props` is of type `{}`
const Home: NextPage = () => { /*...*/ }

When passing props to a NextPage component, you'll also need to pass in your type as an argument.

This will be a TypeScript error because articles does not exist on type {}:

// The `AppProps` annotation types the function argument itself, but with
// no type arguments passed to `NextPage`, `props` is still of type `{}`
const Home: NextPage = ({ articles }: AppProps) => { /*...*/ }

So to give NextPage type information about props, pass AppProps in as a type argument like this:

// you can omit the type annotation from the function argument as `AppProps`
// will be inferred
const Home: NextPage<AppProps> = ({ articles }) => { /*...*/ }

Upvotes: 3

Related Questions