Description
- Replace
enums with strings unions.
export enum GameType {
Singleplayer = "Singleplayer",
Public = "Public",
Private = "Private",
}
export const GameTypeSchema = z.nativeEnum(GameType);
becomes:
export const GameTypeSchema = z.union([
z.literal("Private"),
z.literal("Public"),
z.literal("Singleplayer"),
]);
export type GameType = z.infer<typeof GameTypeSchema>;
- Block
enums with eslint:
{
"rules": {
"no-restricted-syntax": [
"error",
// ban all enums
{
"selector": "TSEnumDeclaration",
"message": "See https://www.youtube.com/watch?v=jjMbPt_H3RQ"
}
]
}
}
Justification
Enums do not behave as you might expect at runtime, because enums are not a native feature of javascript. The typescript compiler creates a strange looking object when you use the enum keyword:

And when you run this weird code, you get this exceptional result:

Things get a little bit better if you set the enum values to strings, but only if the keys and values match. If they do not match, zod will create types based on the key, but the values will actually be used, resulting in schema validation errors.
Description
enums with strings unions.becomes:
enums with eslint:Justification
Enums do not behave as you might expect at runtime, because enums are not a native feature of javascript. The typescript compiler creates a strange looking object when you use the
enumkeyword:And when you run this weird code, you get this exceptional result:
Things get a little bit better if you set the enum values to strings, but only if the keys and values match. If they do not match, zod will create types based on the key, but the values will actually be used, resulting in schema validation errors.