yumba
yumba

Reputation: 1106

Best practice to serialize variables with Date objects in Next.js without losing the type

I want build a table in Next.js using Tanstack Table. I'm using Prisma on top of a MySQL database.

What's the best way to work with Date objects (stored as such in my database) that I want to pass down to be rendered in the table? I know I can serialize and unserialize data to get it working but it strikes me as messy.

When I serialize the data, I am loosing the type when I pass props from getStaticProps to the page.

Is the solution just to avoid using Date objects (ie just keep them serialized) and work with strings?

It would seem good practice to use the type exposed by my database (PostData in the example below) as the type to work with throughout my app. But how to do that without manually casting variables back and forth?

//pages/columns.tsx

const post = Prisma.validator<Prisma.Post>()({
  select: {
    id: true, // type string
    title: true, //type string
    lastModified: true, //type Date
  
});
export type PostData = Prisma.PostGetPayload<typeof post>; //I'm hoping this is the type I can reuse throughout my app, especially when I render the table on the client.


const columnHelper = createColumnHelper<PostData>();

export const columns = [
  columnHelper.accessor("title", {
    header: "Title",
  }),
  columnHelper.accessor("lastModified", {
    header: "Last Modified",
  })
]
//pages/index.tsx

export const getStaticProps: GetStaticProps = async () => {

  //get the data from the DB
  const result = await prisma.post.findMany({
    select: {
      id: true,
      title: true,
      lastModified: true,
    },
  });

  // Serialize data by converting Date objects to string representations
  const data = result.map((row) => ({
    ...row,
    lastModified: row.lastModified.toISOString() // Convert to ISO string representation
  }));

  return {
    props: {
      data,
    },
  };
};


const Home = ({data}) => {

console.log(data) // This works. But data is of type "any" now. 

// I would like data to be of type PostData
// but for that to happen I would now need to convert 'lastModified'
// back to type Date. Manually casting it back to be type Date seems...
// bad practice (?), though I could be wrong.


return (
<>

    //render the table here

</>)
}

export default Home;

Upvotes: 0

Views: 303

Answers (1)

yumba
yumba

Reputation: 1106

Ok, seems like the solution is to install this plugin: https://github.com/blitz-js/next-superjson-plugin

And define the types in getStaticProps like so

interface Props {
  data: PostData[];
}
export const getStaticProps: GetStaticProps<Props> = async () => {...}
const Home = ({ data }: InferGetStaticPropsType<typeof getStaticProps>) => { ... }
...

That way, data is of type PostData[] inside the component as explained here.

Upvotes: 0

Related Questions