arktype icon indicating copy to clipboard operation
arktype copied to clipboard

Branded Types

Open cogell opened this issue 1 year ago • 6 comments

Request a feature

🤷 Motivation

What problem are you having?

In applications having Branded types improves some of the confidence around our code base. We can parse a user email at the edge of the application, brand that with a symbol, and then in components, assume the string we have is indeed a valid email.

// in Zod
const Email = z
  .string()
  .refine(isEmail)
  .brand<"Email">();

Why should we prioritize solving it?

This would be one less hurdle for people moving from zod or io-ts to arktype.

💡 Solution

How do you think we should solve the problem?

Given the Arktype beta future looking toward chaining, perhaps:

const Email = type('string')
  .morph(isEmail)
  .brand("Email");

Why do you think this is the best solution?

Im not highly confident it is. How would with work in the parseOperator...?

cogell avatar May 03 '23 19:05 cogell

It is unlikely this would be built-in as an operator, but would instead be made available as part of our generics implementation via something like Branded. This would also allow it to be chained in a way similar to what you have shown, in addition to:

const email = type("Branded</.*@.*/, 'email'>")

Would depend on #425. That should be one of the first things we tackle after the beta release though.

ssalbdivad avatar May 03 '23 19:05 ssalbdivad

Found this issue while looking to see if there was a built in method.

The below seems to work with the latest version

declare const __brand: unique symbol;

type Branded<T, B> = T & { [__brand]: B };

type Email = Branded<string, 'email'>;

const types = scope({
  "Email": type("email") as Type<Email>
}).export()

image

image

nlynzaad avatar Aug 17 '24 15:08 nlynzaad

I think ideally what I'd like to do is to reuse the existing string.narrowed and number.divisbleBy<1> constructs I have now, but to add some logic to that to allow giving names to custom predicates?

Would be really cool to preserve the set-based comparisons for cases where it's possible.

ssalbdivad avatar Aug 17 '24 15:08 ssalbdivad

Hi. I was wondering if there was any progress on this? (I thought I may have seen some commits related?)

nirweiner2 avatar Sep 08 '24 23:09 nirweiner2

Yes, there's been quite a lot of progress here! There's this very detailed constraint branding system that you will see if you hover over any type you create.

image

At some point soon now that we're approaching a stable 2.0, I will finalize this syntax, the internal type representation, and the APIs and/or configs that can be used to have a type return its branded variant or add arbitrary brands to an existing type.

ssalbdivad avatar Sep 08 '24 23:09 ssalbdivad

I am really looking forward for this to be fully stable. It would allow us to finally migrate from zod and improve our vscode performance :) Thank you very much for all the hard work.

nirweiner2 avatar Sep 11 '24 07:09 nirweiner2