question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Feature request: branded types This issue can be the primary discussion ground for implemented branded types.

Option 1: Replicating io-ts’s symbol trickery to create types like NonZeroNumber or Email (it might be difficult to do that one while remaining ergonomic)

I don’t love all the boilerplate associated with io-ts branded types (i.e. interface PositiveBrand { readonly Positive: unique symbol }).

Option 2

It may be able to include string/number validators as a literal generic argument of the ZodString/ZodNumber classes, like so:

const num: z.number({ max: 5 }) // => z.ZodString
const max5: z.number({ max: 5 }) // => z.ZodString<{ max: 5 }>

That way the validations being enforced are easy to see with a glance at the type definition. This would only work for built-in validators I believe (?). This is also different, in that validations are registered at the instance level instead of the class level.

Issue Analytics

  • State:closed
  • Created 4 years ago
  • Reactions:10
  • Comments:10 (3 by maintainers)

github_iconTop GitHub Comments

10reactions
colinhackscommented, Mar 9, 2021

This is the recommended way to do tagged/branded types in TypeScript/Zod:

type Tagged<T, Tag> = T & { __tag: Tag };
type UUID = Tagged<string, 'UUID'>;

const uuid: z.Schema<UUID> = z.string().uuid() as any;
uuid.safeParse('ae6cd9c2-f2e0-43c5-919c-0640b719aacf'); // Success, data has type UUID
uuid.safeParse(5); // Fail
uuid.safeParse('foo'); // Fail
3reactions
danielo515commented, Jul 4, 2022

This is the recommended way to do tagged/branded types in TypeScript/Zod:

type Tagged<T, Tag> = T & { __tag: Tag };
type UUID = Tagged<string, 'UUID'>;

const uuid: z.Schema<UUID> = z.string().uuid() as any;
uuid.safeParse('ae6cd9c2-f2e0-43c5-919c-0640b719aacf'); // Success, data has type UUID
uuid.safeParse(5); // Fail
uuid.safeParse('foo'); // Fail

Is there any way without using any?

Read more comments on GitHub >

github_iconTop Results From Across the Web

Surviving the TypeScript Ecosystem — Part 6: Branding and ...
Branded (or tagged) types can be used in your code to make it more safe when using common base types. It can also...
Read more >
Typescript Tip: Safer functions with branded types.
This is when we can create a Branded Type. Branded Types. When the base type is too general we can use this pattern....
Read more >
Nominal Typing - TypeScript Deep Dive - Gitbook
Two enum types aren't equal if they differ by name. We can use this fact to provide nominal typing for types that are...
Read more >
Brand: Types of Brands and How to Create a Successful ...
There are numerous types of brands, but the four most common ones include corporate brands, personal brands, product brands, and service brands. What...
Read more >
kourge/ts-brand: Reusable type branding in TypeScript - GitHub
With ts-brand , you can achieve nominal typing by leveraging a technique that is called "type branding" in the TypeScript community. Type branding...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found