One Tip a Week: Zod TypeScript Hack

This week's tip of the week is a TypeScript hack for Zod to get autocomplete suggestions while keeping your types flexible. You might know this hack already from TypeScript, but this is how to do it in Zod.

You can have a string type but still get suggestions in Intellisense while keeping the flexibility of accepting any string. This TypeScript hack has been mentioned by several folks over the past couple of years, but I probably heard about it from Matt Pocock.

You can do this by creating a type alias like this:

type Gravity =
  | "auto"
  | "auto_content_aware" 
  | "center"
  | "custom"
  | "east"
  | "face"
  | (string & {});

let gravity: Gravity = ""; // Try this in VS Code for autocomplete magic

The (string & {}) part is the hack that gives you both autocomplete for known values and the flexibility to use any string.

But what if you're using Zod? Late last year, I had a pull request merged for the cloudinary-util library that shows how to achieve the same thing with Zod schemas:

type Gravity = z.infer<typeof gravitySchema>;

const gravitySchema = z.union([
  z.enum([
    "auto",
    "auto_content_aware",
    "center",
    "custom",
    "east",
    "face",
    "face_center",
    "multi_face",
    "north",
    "north_east",
    "north_west",
    "south",
    "south_east",
    "south_west",
    "west",
  ]),
  // Quirk to allow enum + string
  z.intersection(z.string(), z.object({})),
]);

This lets you get the same autocomplete experience when your team generates TypeScript types from Zod schemas.

That's it! Short and sweet. Until the next one!