Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

How can I get TypeScript to stop complaining about a React rendered value being turned into a Date object?

Next.js, TypeScript, Prisma, Radix-UI project. So I have a loan object that looks something like this

{
    "id": 25,
    "borrowerName": "Test Borrower 1",
    "pipelineStage": "PROSPECT",
    "loanAmount": 500000,
    "transactionType": "PURCHASE",
    "referralSource": "Realtor Lenny",
    "borrowerEmail": "test1@gmail.com",
    "propertyAddress": "1234 Test Way",
    "borrowerPhone": "789-546-3142",
    "purchasePrice": 700000,
    "creditScore": 700,
    "createdAt": "2024-03-15T21:46:18.347Z",
    "updatedAt": "2024-03-15T21:46:18.347Z"
}

I’m trying to build a "view single loan" page. I’m using Prisma, so createdAt and updatedAt are by default strings. Here’s my code for looping over the keys and values in one go:

{Object.keys(loan || {}).map((loanKey) => {
                if (loanKey === "id") return null;

                if (loan && loanKey in loan) {
                  let value: string | number | Date | null =
                    loan[loanKey as keyof typeof loan];

                  if (loanKey === "createdAt" || loanKey === "updatedAt") {
                    value = new Date(value!).toLocaleString(undefined, {
                      year: "numeric",
                      month: "long",
                      day: "numeric",
                      hour: "numeric",
                      minute: "numeric",
                    });
                  }
                  return (
                    <Card className="text-black">
                      <Flex direction={"column"} align={"center"}>
                        <Text>{formatKeyDisplay(loanKey)}: </Text>
                        <Card>{value}</Card>
                      </Flex>
                    </Card>
                  );
                }
                return null;
              })}

I wanted to parse the createdAt and updatedAt strings out of ISO format and into something more user-friendly, so I thought to cast the value into a Date object then use .toLocaleString() to immediately cast it back into a string.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

The issue with that is that I get

Type 'string | Date | null' is not assignable to type 'ReactNode'.
  Type 'Date' is not assignable to type 'ReactNode'.ts(2322)

on trying to render value presumably because TypeScript doesn’t like that value becomes of type Date even if I’m parsing it back into a string immediately.

If I try to type value as so : let value: string | number | null = loan[loanKey as keyof typeof loan]; TypeScript will just complain that

Type 'string | number | Date | null' is not assignable to type 'string | number | null'.
  Type 'Date' is not assignable to type 'string | number | null'.ts(2322)

>Solution :

Use a separate variable for the unprocessed value and the processed value that you know won’t be a Date:

let rawValue: string | number | Date | null =
  loan[loanKey as keyof typeof loan];
let value: string | number | null;

if (loanKey === "createdAt" || loanKey === "updatedAt") {
  value = new Date(rawValue!).toLocaleString(undefined, {
    year: "numeric",
    month: "long",
    day: "numeric",
    hour: "numeric",
    minute: "numeric",
  });
} else if (rawValue instanceof Date) {
  // Throw error, since the keys above are the only ones that
  // show have dates
  throw new Error(`Unexpected Date for field "${loanKey}"`);
} else {
  // This assignment should be fine, because we weeded out `Date` above
  value = rawValue;
}

Playground link

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading