-
Hello, I'm trying to remove the Brand type from an inferred zod type (the branding can happen anywhere), do anyone know how to do this? const schema = z
.object({
name: z.string(),
age: z.number().min(1).int().brand('age'),
})
.brand("schema");
type SchemaWithBrand = z.infer<typeof schema>;
type SchemaWithoutBrand = ??<SchemaWithBrand> |
Beta Was this translation helpful? Give feedback.
Replies: 5 comments 3 replies
-
Is this what you are looking for? const schema = z.object( {
name: z.string(),
age: z.number().min( 1 ).int(),
} ).brand( 'schema' )
type SchemaWithBrand = z.infer<typeof schema>
// type SchemaWithBrand = {
// name: string
// age: number
// } & z.BRAND<'schema'>
type SchemaWithoutBrand = z.infer<typeof schema._def.type>
// type SchemaWithoutBrand = {
// name: string
// age: number
// } If you found my answer satisfactory, please consider supporting me. Even a small amount is greatly appreciated. Thanks friend! 🙏 |
Beta Was this translation helpful? Give feedback.
-
after a little bit of digging, I found this: const schema = z.object( {
name: z.string(),
age: z.number().min( 1 ).int(),
} ).brand( 'schema' )
type SchemaWithBrand = z.infer<typeof schema>
// type SchemaWithBrand = {
// name: string
// age: number
// } & z.BRAND<'schema'>
type SchemaWithoutBrand = Omit<SchemaWithBrand, typeof z.BRAND>
// type SchemaWithoutBrand = {
// name: string
// age: number
// } If you found my answer satisfactory, please consider supporting me. Even a small amount is greatly appreciated. Thanks friend! 🙏 |
Beta Was this translation helpful? Give feedback.
-
Hey @afoures, The following should deeply to unbrand anywhere in the type. Slight disadvantage is that, In case you're passing a branded primitive such as Although if your goal is to infer such as // Our Unbranding Type.
type RemoveBranding<T> = T extends z.ZodType<any, any, infer U> ? z.ZodType<U> : T;
// Usage
let Unbranded: RemoveBranding<typeof mySchema>; |
Beta Was this translation helpful? Give feedback.
-
Hello! To remove the brand type from an inferred zod type, you can use the Omit utility type provided by TypeScript. Here's an example of how you can use it in your code:
The Omit type takes two types of arguments - the first argument is the original type, and the second argument is a union of keys to be removed from the original type. In this case, we want to remove the '__brand' key from the SchemaWithBrand type, which is the key used by zod to store the branding information. So, by using Omit<SchemaWithBrand, '__brand'>, we create a new type that has all the properties of SchemaWithBrand, except for the __brand key. I hope this helps! |
Beta Was this translation helpful? Give feedback.
-
So in the end here is my current solution for this: import { UnionToIntersection } from 'type-fest';
type Primitive =
| string
| number
| boolean
| undefined
| null
| bigint
| Function
| Symbol
| Date
| never
| void;
type IterateOnTuple<T extends [...any[]]> = T extends [
infer Head,
...infer Tail
]
? [Unbrand<Head>, ...IterateOnTuple<Tail>]
: [];
type RemoveBrand<T> = T extends z.BRAND<infer Brand>
? T extends (
| z.BRAND<Brand>
| UnionToIntersection<{ [K in Brand]: z.BRAND<K> }[Brand]>
) &
infer X
? RemoveBrand<X>
: never
: T;
type Unbrand<T> = T extends Primitive
? RemoveBrand<T>
: T extends Promise<infer E>
? Promise<Unbrand<E>>
: T extends [any, ...any[]]
? IterateOnTuple<RemoveBrand<T>>
: T extends Array<infer E>
? Array<Unbrand<E>>
: T extends Set<infer E>
? Set<Unbrand<E>>
: T extends Map<infer E, infer F>
? Map<Unbrand<E>, Unbrand<F>>
: {
[k in Exclude<keyof T, keyof z.BRAND<any>>]: Unbrand<T[k]>;
}; |
Beta Was this translation helpful? Give feedback.
So in the end here is my current solution for this: