Skip to content

Commit 47f04a9

Browse files
committed
feat(guard) reintroduce check as guard
discussion: unlike check, guard is only visible when Output extend Input
1 parent 2aa0a47 commit 47f04a9

File tree

4 files changed

+72
-0
lines changed

4 files changed

+72
-0
lines changed

deno/lib/__tests__/guard.test-d.ts

+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import { describe, expectTypeOf, test } from "vitest";
2+
import { z } from "../index.ts";
3+
4+
describe("guard", () => {
5+
test("work as a type guard when Output extends Input", () => {
6+
expectTypeOf<true>().toEqualTypeOf<true>();
7+
});
8+
test("work as a type guard when Output *does* extend Input", () => {
9+
const inputExtendsOutputSchema = z.object({
10+
a: z.string(),
11+
b: z.enum(["x", "y"]).transform((arg) => arg as string),
12+
});
13+
const val = null as unknown;
14+
if (inputExtendsOutputSchema.guard(val)) {
15+
expectTypeOf(val).toEqualTypeOf<{ a: string; b: string }>();
16+
} else {
17+
expectTypeOf(val).toEqualTypeOf<unknown>();
18+
}
19+
});
20+
21+
test("to be unavailable when Output *does not* extend Input", () => {
22+
const inputDiffersFromOutputSchema = z
23+
.string()
24+
.transform((arg) => parseFloat(arg));
25+
const val = null as unknown;
26+
// @ts-expect-error - compile error as Input does not extend Output
27+
inputDiffersFromOutputSchema.guard(val);
28+
});
29+
});

deno/lib/types.ts

+7
Original file line numberDiff line numberDiff line change
@@ -517,6 +517,13 @@ export abstract class ZodType<
517517
isNullable(): boolean {
518518
return this.safeParse(null).success;
519519
}
520+
521+
guard<T extends Output>(
522+
this: ZodType<T, any, T>,
523+
data: unknown
524+
): data is Output {
525+
return this.safeParse(data).success;
526+
}
520527
}
521528

522529
/////////////////////////////////////////

src/__tests__/guard.test-d.ts

+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import { describe, expectTypeOf, test } from "vitest";
2+
import { z } from "../index";
3+
4+
describe("guard", () => {
5+
test("work as a type guard when Output extends Input", () => {
6+
expectTypeOf<true>().toEqualTypeOf<true>();
7+
});
8+
test("work as a type guard when Output *does* extend Input", () => {
9+
const inputExtendsOutputSchema = z.object({
10+
a: z.string(),
11+
b: z.enum(["x", "y"]).transform((arg) => arg as string),
12+
});
13+
const val = null as unknown;
14+
if (inputExtendsOutputSchema.guard(val)) {
15+
expectTypeOf(val).toEqualTypeOf<{ a: string; b: string }>();
16+
} else {
17+
expectTypeOf(val).toEqualTypeOf<unknown>();
18+
}
19+
});
20+
21+
test("to be unavailable when Output *does not* extend Input", () => {
22+
const inputDiffersFromOutputSchema = z
23+
.string()
24+
.transform((arg) => parseFloat(arg));
25+
const val = null as unknown;
26+
// @ts-expect-error - compile error as Input does not extend Output
27+
inputDiffersFromOutputSchema.guard(val);
28+
});
29+
});

src/types.ts

+7
Original file line numberDiff line numberDiff line change
@@ -517,6 +517,13 @@ export abstract class ZodType<
517517
isNullable(): boolean {
518518
return this.safeParse(null).success;
519519
}
520+
521+
guard<T extends Output>(
522+
this: ZodType<T, any, T>,
523+
data: unknown
524+
): data is Output {
525+
return this.safeParse(data).success;
526+
}
520527
}
521528

522529
/////////////////////////////////////////

0 commit comments

Comments
 (0)