zod icon indicating copy to clipboard operation
zod copied to clipboard

Using the key of string enum using nativeEnum?

Open hls-app opened this issue 1 year ago • 3 comments

So I have been using this Country enum and wondering if we can validate the keys instead of the value?

https://gist.github.com/evolkmann/740d24889c509c08484a8ff72af5dd64

Currently, the nativeEnum validates the value and could not find an option to make it validate the key instead.

hls-app avatar Jul 03 '24 15:07 hls-app

Currently using this as I cannot flip the enum just for Zod

z.string().length(2).regex(/^[A-Z]{2}$/, 'Invalid country code').nullable()

hls-app avatar Jul 06 '24 03:07 hls-app

This how I did it

z.enum(Object.keys(Enum) as [keyof typeof Enum, ...(keyof typeof Enum[]])

Let me know if you have a better idea than this.

nabil-rady avatar Jul 06 '24 11:07 nabil-rady

Hi, @hls-app. I'm Dosu, and I'm helping the Zod team manage their backlog. I'm marking this issue as stale.

Issue Summary:

  • You were looking for a way to validate the keys of a string enum using nativeEnum in Zod.
  • You shared a workaround using regex for country codes.
  • User @nabil-rady suggested using z.enum(Object.keys(Enum) as [keyof typeof Enum, ...(keyof typeof Enum[])]).
  • You acknowledged this suggestion with a thumbs-up, indicating it might be helpful.

Next Steps:

  • Please let me know if this issue is still relevant to the latest version of Zod. If so, you can keep the discussion open by commenting here.
  • Otherwise, this issue will be automatically closed in 7 days.

Thank you for your understanding and contribution!

dosubot[bot] avatar Jun 17 '25 16:06 dosubot[bot]

Zod's z.nativeEnum and z.enum only validate enum values, not keys—there's no built-in way to validate enum keys directly with these methods (docs, code). Your current regex-based workaround is totally reasonable for ISO country codes, but if you want to ensure the string is actually a key of your Country enum, you can use a custom refinement for type safety:

import { z } from "zod";
import { Country } from "./your-enum-file";

const countryKeySchema = z
  .string()
  .refine((val) => Object.keys(Country).includes(val), {
    message: "Invalid country code",
  })
  .nullable();

This checks that the input is one of the enum's keys at runtime. If you ever can generate a list of keys at build time, you could use z.enum(Object.keys(Country) as [keyof typeof Country]), but that's not always ergonomic with TypeScript enums.

Let me know if this solves your problem—if so, feel free to close the issue!

To reply, just mention @dosu.


How did I do? Good | Irrelevant | Incorrect | Verbose | Hallucination | Report 🐛 | Other  Join Discord Share on X

dosubot[bot] avatar Jul 21 '25 23:07 dosubot[bot]