arktype
arktype copied to clipboard
Branded Types
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
...?
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.
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()
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.
Hi. I was wondering if there was any progress on this? (I thought I may have seen some commits related?)
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.
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.
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.