Zod's nativeEnum function verifies the value of an enum

Utilizing a zod schema to validate an object containing an enum field:

enum Colour {
    red: 'Red',
    blue: 'Blue',
}

const schema = z.object({
    colour: z.nativeEnum(Colour),
});

Received data from an API includes color values as either 'red' or 'blue', and the goal is to validate this using the provided schema. However, the nativeEnum function in the schema validates based on capitalized enum cases rather than the enum properties themselves:

enum Colour {
    red: 'Red',
    blue: 'Blue',
}

const schema = z.object({
    colour: z.nativeEnum(Colour),
});

const rawInput1 = {
    colour: 'red' // should be considered valid
};
const parsedInput1 = schema.parse(rawInput1); // this validation fails

const rawInput2 = {
    colour: 'Red' // should be considered invalid
};
const parsedInput2 = schema.parse(rawInput2); // this validation passes

Is there a way to make zod validate based on the property in the enum instead of just the value? And why does this occur?

The reason for wanting to parse the enum properties and defining the enum that way is to utilize the colour variable to extract its string value within the enum: Colour[parsedInput1.colour]. This wouldn't be achievable if colour remains the string value.

Answer №1

If you want to validate based on the keys using a regular .enum() method, you can extract the enum keys with Object.keys():

enum Colour {
    red = 'Red',
    blue = 'Blue',
}

const keys = Object.keys(Colours) // ["red", "blue"]

const schema = z.object({
    colour: z.enum(keys),
});

One issue is that the type of keys in this case is string[] instead of

["red", "blue"]
(even though it will be the actual value at runtime). So it will function correctly, but without TypeScript validation...

Using keyof typeof, you can create a union of the enum's keys:

type KeyUnion = keyof typeof Colour // "red" | "blue"

To achieve the desired result, you need to "lie to typescript" a bit by casting the keys type:

const keys = Object.keys(Colours) as [keyof typeof Colour]
const schema = z.object({
    colour: z.enum(keys),
});

This approach allows for functionality both at the type level and at runtime.

It's important to note that keys is not actually of type [keyof typeof Colour]; this is simply a workaround we use to ensure correct inference.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Unable to execute any actions on object in JavaScript

I currently have two functions in my code: getRawData() and getBTRawData(). The purpose of getBTRawData() function is to retrieve data from Bluetooth connected to a mobile device. On the other hand, getRawData() function takes the return value from getB ...

Attempting to locate an element within the DOM using TypeScript

I am completely new to TypeScript. I have been attempting to locate an element using a selector, but no matter what I tried, the findElement() method always returns undefined. Can someone please point out where my mistake might be? Any assistance would b ...

Typescript: Omitting mandatory fields from a type

Can anyone help me with defining the type ExcludeAllRequiredProps<T> in the code below to exclude all required properties? Any assistance would be greatly appreciated. Thank you. type A = { a: number, b: number, c?: number, d?: number } typ ...

Issue with TypeScript: Error appears when importing express after running "npm i @types/express -D"

Struggling with adding the following line of code in an index.ts file: import express, { Application } from 'express'; Initially encountered an error with "from 'express'", so I ran npm i @types/express -D which fixed that is ...

Having trouble launching the freshly developed Angular app

I'm encountering an issue with my newly created app - I can't seem to launch it. Error: The loader “C:/C#/Angular/my-app/src/app/app.component.css” is not providing a string as expected. https://i.sstatic.net/6Xjwd.png https://i.sstatic.ne ...

TypeScript and Node.js: The type of 'this' is implicitly set to 'any'

Help Needed with TypeScript issue: An issue is arising in my TypeScript code related to a mongoose schema's post function. It is used to generate a profile for a user upon signing up, using the User model. Even though the code functions properly, th ...

Chakra UI Icons in Next.js App Triggering Unsupportive "export *" Bug

Description: Currently, I am developing a Next.js application and incorporating the Chakra UI library for styling and components. However, I have run into an obstacle with the Chakra UI icons package during the build process. Error Message: ./node_module ...

Is there a way to have my accordion adjust automatically?

I have developed a dynamic accordion component that populates its values from the parent component. However, I am facing an issue where each accordion does not respond individually to clicks. Whenever I click on any accordion, only the first one expands an ...

Error message in Angular states that it is not possible to bind to 'formGroup' because it is not recognized as a property of 'form' within Angular

When trying to extract data from a form using formcontrol, everything seems to be working fine except for the [formcontrol] = "userForm" in the HTML. If I remove this part, the project runs smoothly. I have tried multiple tutorials but none of them seem ...

Refining Angular service coding techniques

In my application, I have implemented this specific format to interact with an API and retrieve data from it. Below is the code snippet taken from one of the service.ts files: getCheckoutDetails(): Observable<UserDetail> { let query = `7668`; ...

Having trouble getting this multi-select feature to function properly in Reactjs with Typescript? Let's figure out the solution together

I encountered an issue where I was unable to select multiple items due to a join error code "Property 'join' does not exist on type 'unknown'." in a .tsx file const DropdownMultiselect =()=> { return( <> ...

Eliminate all citation markers in the final compiled result

Currently, I am consolidating all my .ts files into a single file using the following command: tsc -out app.js app.ts --removeComments This is based on the instructions provided in the npm documentation. However, even after compilation, all reference tag ...

Ways to simulate a dependent class in TypeScript & JEST without modifying constructor parameters to optional

Currently, I am attempting to replicate a well-known process in Java development using TypeScript and JEST for practice. In this scenario, there is a Controller class that relies on a Service class. The connection between the two is established through the ...

Encountering a 404 (Not Found) error while trying to access a null resource in Angular at http://localhost

Currently, I am developing an angular application with ng9. I have a specific div where I need to display an avatar using an image fetched from the API in my component.ts file: .... export class HomeComponent implements OnInit { nextLaunch$: Observabl ...

Apollo Client's useQuery function is causing unnecessary refetches when using Next.js' router.push method

Currently, I'm facing an issue where a query within a useQuery Apollo Client hook is being re-run unnecessarily every time Next.js's router.push function is triggered. The problem code snippet looks like this: const Parent = () => { useQuery ...

Testing components in React involves creating or invoking specific construct or call signatures

Exploring this React component: import { Meta } from '@storybook/react'; export function MyComponentExample() { return ( <div>my component example</div> ); } export default { component: MyComponentExample, title: 'M ...

Verification based on conditions for Angular reactive forms

I am currently learning Angular and working on creating a reactive form. Within my HTML table, I have generated controls by looping through the data. I am looking to add validation based on the following cases: Upon page load, the Save button should be ...

Having trouble retrieving the "history" from props?

I am working with a React component. import * as React from 'react'; import { Component } from 'react'; import { FormControl, Button } from 'react-bootstrap'; type Props = { history: any[]; }; // Question on defining Prop ...

How can I modify my Axios Post request to receive a 201 status code in order to successfully save the data?

I am facing an issue when attempting to make a POST request locally with Axios on my NodeJS front-end app to my .NET core local server. The server returns a 204 status code and the axios request returns a pending promise. How can I change this to achieve a ...

Creating a dynamic table in HTML and Angular is a simple process that involves utilizing the

How can I create an HTML table dynamically without knowing the template of each row in advance? Sometimes it may have 2 columns, sometimes 4... I am looking for something like this: <div> <h1>Angular HTML Table Example</h1> < ...