Skip to content

Commit

Permalink
3.18 (#1323)
Browse files Browse the repository at this point in the history
* 3.18

* Fix tests

Co-authored-by: Colin McDonnell <colinmcd@alum.mit.edu>
  • Loading branch information
colinhacks and Colin McDonnell committed Aug 9, 2022
1 parent 7c113ab commit 5976824
Show file tree
Hide file tree
Showing 5 changed files with 29 additions and 41 deletions.
28 changes: 11 additions & 17 deletions deno/lib/__tests__/branded.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,44 +14,38 @@ test("branded types", () => {

// simple branding
type MySchema = z.infer<typeof mySchema>;
const f1: util.AssertEqual<
util.assertEqual<
MySchema,
{ name: string } & { [z.BRAND]: { superschema: true } }
> = true;
f1;
>(true);

const doStuff = (arg: MySchema) => arg;
doStuff(mySchema.parse({ name: "hello there" }));

// inheritance
const extendedSchema = mySchema.brand<"subschema">();
type ExtendedSchema = z.infer<typeof extendedSchema>;
const f2: util.AssertEqual<
util.assertEqual<
ExtendedSchema,
{ name: string } & { [z.BRAND]: { superschema: true; subschema: true } }
> = true;
f2;
{ name: string } & z.BRAND<"superschema"> & z.BRAND<"subschema">
>(true);

doStuff(extendedSchema.parse({ name: "hello again" }));

// number branding
const numberSchema = z.number().brand<42>();
type NumberSchema = z.infer<typeof numberSchema>;
const f3: util.AssertEqual<
NumberSchema,
number & { [z.BRAND]: { 42: true } }
> = true;
f3;
util.assertEqual<NumberSchema, number & { [z.BRAND]: { 42: true } }>(true);

// symbol branding
const MyBrand: unique symbol = Symbol("hello");
type MyBrand = typeof MyBrand;
const symbolBrand = z.number().brand<"sup">().brand<typeof MyBrand>();
type SymbolBrand = z.infer<typeof symbolBrand>;
// number & { [z.BRAND]: { sup: true, [MyBrand]: true } }
const f4: util.AssertEqual<
SymbolBrand,
number & { [z.BRAND]: { sup: true; [MyBrand]: true } }
> = true;
f4;
util.assertEqual<SymbolBrand, number & z.BRAND<"sup"> & z.BRAND<MyBrand>>(
true
);

// @ts-expect-error
doStuff({ name: "hello there!" });
Expand Down
6 changes: 3 additions & 3 deletions deno/lib/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3740,17 +3740,17 @@ export interface ZodBrandedDef<T extends ZodTypeAny> extends ZodTypeDef {
}

export const BRAND: unique symbol = Symbol("zod_brand");
type Brand<T extends string | number | symbol> = {
export type BRAND<T extends string | number | symbol> = {
[BRAND]: { [k in T]: true };
};

export class ZodBranded<
T extends ZodTypeAny,
B extends string | number | symbol
> extends ZodType<
T["_output"] & Brand<B>,
T["_output"] & BRAND<B>,
ZodBrandedDef<T>,
T["_input"] & Brand<B>
T["_input"] & BRAND<B>
> {
_parse(input: ParseInput): ParseReturnType<any> {
const { ctx } = this._processInputParams(input);
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "zod",
"version": "3.17.10",
"version": "3.18.0",
"description": "TypeScript-first schema declaration and validation library with static type inference",
"main": "./lib/index.js",
"types": "./index.d.ts",
Expand Down
28 changes: 11 additions & 17 deletions src/__tests__/branded.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,44 +13,38 @@ test("branded types", () => {

// simple branding
type MySchema = z.infer<typeof mySchema>;
const f1: util.AssertEqual<
util.assertEqual<
MySchema,
{ name: string } & { [z.BRAND]: { superschema: true } }
> = true;
f1;
>(true);

const doStuff = (arg: MySchema) => arg;
doStuff(mySchema.parse({ name: "hello there" }));

// inheritance
const extendedSchema = mySchema.brand<"subschema">();
type ExtendedSchema = z.infer<typeof extendedSchema>;
const f2: util.AssertEqual<
util.assertEqual<
ExtendedSchema,
{ name: string } & { [z.BRAND]: { superschema: true; subschema: true } }
> = true;
f2;
{ name: string } & z.BRAND<"superschema"> & z.BRAND<"subschema">
>(true);

doStuff(extendedSchema.parse({ name: "hello again" }));

// number branding
const numberSchema = z.number().brand<42>();
type NumberSchema = z.infer<typeof numberSchema>;
const f3: util.AssertEqual<
NumberSchema,
number & { [z.BRAND]: { 42: true } }
> = true;
f3;
util.assertEqual<NumberSchema, number & { [z.BRAND]: { 42: true } }>(true);

// symbol branding
const MyBrand: unique symbol = Symbol("hello");
type MyBrand = typeof MyBrand;
const symbolBrand = z.number().brand<"sup">().brand<typeof MyBrand>();
type SymbolBrand = z.infer<typeof symbolBrand>;
// number & { [z.BRAND]: { sup: true, [MyBrand]: true } }
const f4: util.AssertEqual<
SymbolBrand,
number & { [z.BRAND]: { sup: true; [MyBrand]: true } }
> = true;
f4;
util.assertEqual<SymbolBrand, number & z.BRAND<"sup"> & z.BRAND<MyBrand>>(
true
);

// @ts-expect-error
doStuff({ name: "hello there!" });
Expand Down
6 changes: 3 additions & 3 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3740,17 +3740,17 @@ export interface ZodBrandedDef<T extends ZodTypeAny> extends ZodTypeDef {
}

export const BRAND: unique symbol = Symbol("zod_brand");
type Brand<T extends string | number | symbol> = {
export type BRAND<T extends string | number | symbol> = {
[BRAND]: { [k in T]: true };
};

export class ZodBranded<
T extends ZodTypeAny,
B extends string | number | symbol
> extends ZodType<
T["_output"] & Brand<B>,
T["_output"] & BRAND<B>,
ZodBrandedDef<T>,
T["_input"] & Brand<B>
T["_input"] & BRAND<B>
> {
_parse(input: ParseInput): ParseReturnType<any> {
const { ctx } = this._processInputParams(input);
Expand Down

0 comments on commit 5976824

Please sign in to comment.