zod 4.3.0-canary.20251222T061611 → 4.3.0-canary.20251222T195342

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zod",
3
- "version": "4.3.0-canary.20251222T061611",
3
+ "version": "4.3.0-canary.20251222T195342",
4
4
  "type": "module",
5
5
  "license": "MIT",
6
6
  "author": "Colin McDonnell <zod@colinhacks.com>",
@@ -48,7 +48,9 @@ export interface ZodType<
48
48
  : ["Incompatible schema"]
49
49
  ): this;
50
50
 
51
- brand<T extends PropertyKey = PropertyKey>(value?: T): PropertyKey extends T ? this : core.$ZodBranded<this, T>;
51
+ brand<T extends PropertyKey = PropertyKey, Dir extends "in" | "out" | "inout" = "out">(
52
+ value?: T
53
+ ): PropertyKey extends T ? this : core.$ZodBranded<this, T, Dir>;
52
54
 
53
55
  // parsing
54
56
  parse(data: unknown, params?: core.ParseContext<core.$ZodIssue>): core.output<this>;
@@ -61,3 +61,46 @@ test("branded record", () => {
61
61
  type recordWithBrandedNumberKeys = z.infer<typeof recordWithBrandedNumberKeys>;
62
62
  expectTypeOf<recordWithBrandedNumberKeys>().toEqualTypeOf<Record<string & z.core.$brand<"SomeBrand">, number>>();
63
63
  });
64
+
65
+ test("brand direction: out (default)", () => {
66
+ const schema = z.string().brand<"A">();
67
+ type Input = z.input<typeof schema>;
68
+ type Output = z.output<typeof schema>;
69
+
70
+ // output is branded
71
+ expectTypeOf<Output>().toEqualTypeOf<string & z.$brand<"A">>();
72
+ // input is NOT branded (default behavior)
73
+ expectTypeOf<Input>().toEqualTypeOf<string>();
74
+ });
75
+
76
+ test("brand direction: out (explicit)", () => {
77
+ const schema = z.string().brand<"A", "out">();
78
+ type Input = z.input<typeof schema>;
79
+ type Output = z.output<typeof schema>;
80
+
81
+ // output is branded
82
+ expectTypeOf<Output>().toEqualTypeOf<string & z.$brand<"A">>();
83
+ // input is NOT branded
84
+ expectTypeOf<Input>().toEqualTypeOf<string>();
85
+ });
86
+
87
+ test("brand direction: in", () => {
88
+ const schema = z.string().brand<"A", "in">();
89
+ type Input = z.input<typeof schema>;
90
+ type Output = z.output<typeof schema>;
91
+
92
+ // input is branded
93
+ expectTypeOf<Input>().toEqualTypeOf<string & z.$brand<"A">>();
94
+ // output is NOT branded
95
+ expectTypeOf<Output>().toEqualTypeOf<string>();
96
+ });
97
+
98
+ test("brand direction: inout", () => {
99
+ const schema = z.string().brand<"A", "inout">();
100
+ type Input = z.input<typeof schema>;
101
+ type Output = z.output<typeof schema>;
102
+
103
+ // both are branded
104
+ expectTypeOf<Input>().toEqualTypeOf<string & z.$brand<"A">>();
105
+ expectTypeOf<Output>().toEqualTypeOf<string & z.$brand<"A">>();
106
+ });
@@ -82,8 +82,16 @@ export type $brand<T extends string | number | symbol = string | number | symbol
82
82
  [$brand]: { [k in T]: true };
83
83
  };
84
84
 
85
- export type $ZodBranded<T extends schemas.SomeType, Brand extends string | number | symbol> = T &
86
- Record<"_zod", Record<"output", output<T> & $brand<Brand>>>;
85
+ export type $ZodBranded<
86
+ T extends schemas.SomeType,
87
+ Brand extends string | number | symbol,
88
+ Dir extends "in" | "out" | "inout" = "out",
89
+ > = T &
90
+ (Dir extends "inout"
91
+ ? { _zod: { input: input<T> & $brand<Brand>; output: output<T> & $brand<Brand> } }
92
+ : Dir extends "in"
93
+ ? { _zod: { input: input<T> & $brand<Brand> } }
94
+ : { _zod: { output: output<T> & $brand<Brand> } });
87
95
 
88
96
  export class $ZodAsyncError extends Error {
89
97
  constructor() {
@@ -20,9 +20,9 @@ export interface ZodMiniType<
20
20
  : [core.$replace<R["_meta"], this>]
21
21
  : ["Incompatible schema"]
22
22
  ): this;
23
- brand<T extends PropertyKey = PropertyKey>(
23
+ brand<T extends PropertyKey = PropertyKey, Dir extends "in" | "out" | "inout" = "out">(
24
24
  value?: T
25
- ): PropertyKey extends T ? this : this & Record<"_zod", Record<"output", core.output<this> & core.$brand<T>>>;
25
+ ): PropertyKey extends T ? this : core.$ZodBranded<this, T, Dir>;
26
26
 
27
27
  def: Internals["def"];
28
28
 
@@ -49,3 +49,46 @@ test("branded types", () => {
49
49
  // @ts-expect-error
50
50
  doStuff({ name: "hello there!" });
51
51
  });
52
+
53
+ test("brand direction: out (default)", () => {
54
+ const schema = z.string().brand<"A">();
55
+ type Input = z.input<typeof schema>;
56
+ type Output = z.output<typeof schema>;
57
+
58
+ // output is branded
59
+ expectTypeOf<Output>().toEqualTypeOf<string & z.$brand<"A">>();
60
+ // input is NOT branded (default behavior)
61
+ expectTypeOf<Input>().toEqualTypeOf<string>();
62
+ });
63
+
64
+ test("brand direction: out (explicit)", () => {
65
+ const schema = z.string().brand<"A", "out">();
66
+ type Input = z.input<typeof schema>;
67
+ type Output = z.output<typeof schema>;
68
+
69
+ // output is branded
70
+ expectTypeOf<Output>().toEqualTypeOf<string & z.$brand<"A">>();
71
+ // input is NOT branded
72
+ expectTypeOf<Input>().toEqualTypeOf<string>();
73
+ });
74
+
75
+ test("brand direction: in", () => {
76
+ const schema = z.string().brand<"A", "in">();
77
+ type Input = z.input<typeof schema>;
78
+ type Output = z.output<typeof schema>;
79
+
80
+ // input is branded
81
+ expectTypeOf<Input>().toEqualTypeOf<string & z.$brand<"A">>();
82
+ // output is NOT branded
83
+ expectTypeOf<Output>().toEqualTypeOf<string>();
84
+ });
85
+
86
+ test("brand direction: inout", () => {
87
+ const schema = z.string().brand<"A", "inout">();
88
+ type Input = z.input<typeof schema>;
89
+ type Output = z.output<typeof schema>;
90
+
91
+ // both are branded
92
+ expectTypeOf<Input>().toEqualTypeOf<string & z.$brand<"A">>();
93
+ expectTypeOf<Output>().toEqualTypeOf<string & z.$brand<"A">>();
94
+ });
@@ -20,7 +20,7 @@ export interface ZodType<out Output = unknown, out Input = unknown, out Internal
20
20
  parent: boolean;
21
21
  }): this;
22
22
  register<R extends core.$ZodRegistry>(registry: R, ...meta: this extends R["_schema"] ? undefined extends R["_meta"] ? [core.$replace<R["_meta"], this>?] : [core.$replace<R["_meta"], this>] : ["Incompatible schema"]): this;
23
- brand<T extends PropertyKey = PropertyKey>(value?: T): PropertyKey extends T ? this : core.$ZodBranded<this, T>;
23
+ brand<T extends PropertyKey = PropertyKey, Dir extends "in" | "out" | "inout" = "out">(value?: T): PropertyKey extends T ? this : core.$ZodBranded<this, T, Dir>;
24
24
  parse(data: unknown, params?: core.ParseContext<core.$ZodIssue>): core.output<this>;
25
25
  safeParse(data: unknown, params?: core.ParseContext<core.$ZodIssue>): parse.ZodSafeParseResult<core.output<this>>;
26
26
  parseAsync(data: unknown, params?: core.ParseContext<core.$ZodIssue>): Promise<core.output<this>>;
@@ -20,7 +20,7 @@ export interface ZodType<out Output = unknown, out Input = unknown, out Internal
20
20
  parent: boolean;
21
21
  }): this;
22
22
  register<R extends core.$ZodRegistry>(registry: R, ...meta: this extends R["_schema"] ? undefined extends R["_meta"] ? [core.$replace<R["_meta"], this>?] : [core.$replace<R["_meta"], this>] : ["Incompatible schema"]): this;
23
- brand<T extends PropertyKey = PropertyKey>(value?: T): PropertyKey extends T ? this : core.$ZodBranded<this, T>;
23
+ brand<T extends PropertyKey = PropertyKey, Dir extends "in" | "out" | "inout" = "out">(value?: T): PropertyKey extends T ? this : core.$ZodBranded<this, T, Dir>;
24
24
  parse(data: unknown, params?: core.ParseContext<core.$ZodIssue>): core.output<this>;
25
25
  safeParse(data: unknown, params?: core.ParseContext<core.$ZodIssue>): parse.ZodSafeParseResult<core.output<this>>;
26
26
  parseAsync(data: unknown, params?: core.ParseContext<core.$ZodIssue>): Promise<core.output<this>>;
@@ -22,7 +22,20 @@ export type $brand<T extends string | number | symbol = string | number | symbol
22
22
  [k in T]: true;
23
23
  };
24
24
  };
25
- export type $ZodBranded<T extends schemas.SomeType, Brand extends string | number | symbol> = T & Record<"_zod", Record<"output", output<T> & $brand<Brand>>>;
25
+ export type $ZodBranded<T extends schemas.SomeType, Brand extends string | number | symbol, Dir extends "in" | "out" | "inout" = "out"> = T & (Dir extends "inout" ? {
26
+ _zod: {
27
+ input: input<T> & $brand<Brand>;
28
+ output: output<T> & $brand<Brand>;
29
+ };
30
+ } : Dir extends "in" ? {
31
+ _zod: {
32
+ input: input<T> & $brand<Brand>;
33
+ };
34
+ } : {
35
+ _zod: {
36
+ output: output<T> & $brand<Brand>;
37
+ };
38
+ });
26
39
  export declare class $ZodAsyncError extends Error {
27
40
  constructor();
28
41
  }
package/v4/core/core.d.ts CHANGED
@@ -22,7 +22,20 @@ export type $brand<T extends string | number | symbol = string | number | symbol
22
22
  [k in T]: true;
23
23
  };
24
24
  };
25
- export type $ZodBranded<T extends schemas.SomeType, Brand extends string | number | symbol> = T & Record<"_zod", Record<"output", output<T> & $brand<Brand>>>;
25
+ export type $ZodBranded<T extends schemas.SomeType, Brand extends string | number | symbol, Dir extends "in" | "out" | "inout" = "out"> = T & (Dir extends "inout" ? {
26
+ _zod: {
27
+ input: input<T> & $brand<Brand>;
28
+ output: output<T> & $brand<Brand>;
29
+ };
30
+ } : Dir extends "in" ? {
31
+ _zod: {
32
+ input: input<T> & $brand<Brand>;
33
+ };
34
+ } : {
35
+ _zod: {
36
+ output: output<T> & $brand<Brand>;
37
+ };
38
+ });
26
39
  export declare class $ZodAsyncError extends Error {
27
40
  constructor();
28
41
  }
@@ -8,7 +8,7 @@ export interface ZodMiniType<out Output = unknown, out Input = unknown, out Inte
8
8
  parent: boolean;
9
9
  }): this;
10
10
  register<R extends core.$ZodRegistry>(registry: R, ...meta: this extends R["_schema"] ? undefined extends R["_meta"] ? [core.$replace<R["_meta"], this>?] : [core.$replace<R["_meta"], this>] : ["Incompatible schema"]): this;
11
- brand<T extends PropertyKey = PropertyKey>(value?: T): PropertyKey extends T ? this : this & Record<"_zod", Record<"output", core.output<this> & core.$brand<T>>>;
11
+ brand<T extends PropertyKey = PropertyKey, Dir extends "in" | "out" | "inout" = "out">(value?: T): PropertyKey extends T ? this : core.$ZodBranded<this, T, Dir>;
12
12
  def: Internals["def"];
13
13
  parse(data: unknown, params?: core.ParseContext<core.$ZodIssue>): core.output<this>;
14
14
  safeParse(data: unknown, params?: core.ParseContext<core.$ZodIssue>): util.SafeParseResult<core.output<this>>;
@@ -8,7 +8,7 @@ export interface ZodMiniType<out Output = unknown, out Input = unknown, out Inte
8
8
  parent: boolean;
9
9
  }): this;
10
10
  register<R extends core.$ZodRegistry>(registry: R, ...meta: this extends R["_schema"] ? undefined extends R["_meta"] ? [core.$replace<R["_meta"], this>?] : [core.$replace<R["_meta"], this>] : ["Incompatible schema"]): this;
11
- brand<T extends PropertyKey = PropertyKey>(value?: T): PropertyKey extends T ? this : this & Record<"_zod", Record<"output", core.output<this> & core.$brand<T>>>;
11
+ brand<T extends PropertyKey = PropertyKey, Dir extends "in" | "out" | "inout" = "out">(value?: T): PropertyKey extends T ? this : core.$ZodBranded<this, T, Dir>;
12
12
  def: Internals["def"];
13
13
  parse(data: unknown, params?: core.ParseContext<core.$ZodIssue>): core.output<this>;
14
14
  safeParse(data: unknown, params?: core.ParseContext<core.$ZodIssue>): util.SafeParseResult<core.output<this>>;