Skip to content

Commit

Permalink
Merge pull request #898 from noyan-alimov/nan-type
Browse files Browse the repository at this point in the history
NaN type
  • Loading branch information
colinhacks authored Mar 1, 2022
2 parents a8241de + beec3bf commit 4a549b1
Show file tree
Hide file tree
Showing 8 changed files with 138 additions and 1 deletion.
12 changes: 12 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ These docs have been translated into [Chinese](./README_ZH.md).
- [Literals](#literals)
- [Strings](#strings)
- [Numbers](#numbers)
- [NaNs](#nans)
- [Booleans](#booleans)
- [Dates](#dates)
- [Zod enums](#zod-enums)
Expand Down Expand Up @@ -403,6 +404,17 @@ Optionally, you can pass in a second argument to provide a custom error message.
z.number().lte(5, { message: "this👏is👏too👏big" });
```

## NaNs

You can customize certain error messages when creating a nan schema.

```ts
const isNaN = z.nan({
required_error: "isNaN is required",
invalid_type_error: "isNaN must be not a number",
});
```

## Booleans

You can customize certain error messages when creating a boolean schema.
Expand Down
2 changes: 1 addition & 1 deletion coverage.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 2 additions & 0 deletions deno/lib/__tests__/firstparty.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ test("first party switch", () => {
break;
case z.ZodFirstPartyTypeKind.ZodNumber:
break;
case z.ZodFirstPartyTypeKind.ZodNaN:
break;
case z.ZodFirstPartyTypeKind.ZodBigInt:
break;
case z.ZodFirstPartyTypeKind.ZodBoolean:
Expand Down
22 changes: 22 additions & 0 deletions deno/lib/__tests__/nan.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// @ts-ignore TS6133
import { expect } from "https://deno.land/x/expect@v0.2.6/mod.ts";
const test = Deno.test;

import * as z from "../index.ts";

const schema = z.nan();

test("passing validations", () => {
schema.parse(NaN);
schema.parse(Number("Not a number"));
});

test("failing validations", () => {
expect(() => schema.parse(5)).toThrow();
expect(() => schema.parse("John")).toThrow();
expect(() => schema.parse(true)).toThrow();
expect(() => schema.parse(null)).toThrow();
expect(() => schema.parse(undefined)).toThrow();
expect(() => schema.parse({})).toThrow();
expect(() => schema.parse([])).toThrow();
});
39 changes: 39 additions & 0 deletions deno/lib/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3434,6 +3434,41 @@ export class ZodDefault<T extends ZodTypeAny> extends ZodType<
};
}

/////////////////////////////////////////
/////////////////////////////////////////
////////// //////////
////////// ZodNaN //////////
////////// //////////
/////////////////////////////////////////
/////////////////////////////////////////

export interface ZodNaNDef extends ZodTypeDef {
typeName: ZodFirstPartyTypeKind.ZodNaN;
}

export class ZodNaN extends ZodType<number, ZodNaNDef> {
_parse(input: ParseInput): ParseReturnType<any> {
const { status, ctx } = this._processInputParams(input);
if (ctx.parsedType !== ZodParsedType.nan) {
addIssueToContext(ctx, {
code: ZodIssueCode.invalid_type,
expected: ZodParsedType.nan,
received: ctx.parsedType,
});
return INVALID;
}

return { status: status.value, value: ctx.data };
}

static create = (params?: RawCreateParams): ZodNaN => {
return new ZodNaN({
typeName: ZodFirstPartyTypeKind.ZodNaN,
...processCreateParams(params),
});
};
}

export const custom = <T>(
check?: (data: unknown) => any,
params?: Parameters<ZodTypeAny["refine"]>[1]
Expand All @@ -3451,6 +3486,7 @@ export const late = {
export enum ZodFirstPartyTypeKind {
ZodString = "ZodString",
ZodNumber = "ZodNumber",
ZodNaN = "ZodNaN",
ZodBigInt = "ZodBigInt",
ZodBoolean = "ZodBoolean",
ZodDate = "ZodDate",
Expand Down Expand Up @@ -3483,6 +3519,7 @@ export enum ZodFirstPartyTypeKind {
export type ZodFirstPartySchemaTypes =
| ZodString
| ZodNumber
| ZodNaN
| ZodBigInt
| ZodBoolean
| ZodDate
Expand Down Expand Up @@ -3520,6 +3557,7 @@ const instanceOfType = <T extends new (...args: any[]) => any>(

const stringType = ZodString.create;
const numberType = ZodNumber.create;
const nanType = ZodNaN.create;
const bigIntType = ZodBigInt.create;
const booleanType = ZodBoolean.create;
const dateType = ZodDate.create;
Expand Down Expand Up @@ -3568,6 +3606,7 @@ export {
lazyType as lazy,
literalType as literal,
mapType as map,
nanType as nan,
nativeEnumType as nativeEnum,
neverType as never,
nullType as null,
Expand Down
2 changes: 2 additions & 0 deletions src/__tests__/firstparty.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ test("first party switch", () => {
break;
case z.ZodFirstPartyTypeKind.ZodNumber:
break;
case z.ZodFirstPartyTypeKind.ZodNaN:
break;
case z.ZodFirstPartyTypeKind.ZodBigInt:
break;
case z.ZodFirstPartyTypeKind.ZodBoolean:
Expand Down
21 changes: 21 additions & 0 deletions src/__tests__/nan.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// @ts-ignore TS6133
import { expect, test } from "@jest/globals";

import * as z from "../index";

const schema = z.nan();

test("passing validations", () => {
schema.parse(NaN);
schema.parse(Number("Not a number"));
});

test("failing validations", () => {
expect(() => schema.parse(5)).toThrow();
expect(() => schema.parse("John")).toThrow();
expect(() => schema.parse(true)).toThrow();
expect(() => schema.parse(null)).toThrow();
expect(() => schema.parse(undefined)).toThrow();
expect(() => schema.parse({})).toThrow();
expect(() => schema.parse([])).toThrow();
});
39 changes: 39 additions & 0 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3434,6 +3434,41 @@ export class ZodDefault<T extends ZodTypeAny> extends ZodType<
};
}

/////////////////////////////////////////
/////////////////////////////////////////
////////// //////////
////////// ZodNaN //////////
////////// //////////
/////////////////////////////////////////
/////////////////////////////////////////

export interface ZodNaNDef extends ZodTypeDef {
typeName: ZodFirstPartyTypeKind.ZodNaN;
}

export class ZodNaN extends ZodType<number, ZodNaNDef> {
_parse(input: ParseInput): ParseReturnType<any> {
const { status, ctx } = this._processInputParams(input);
if (ctx.parsedType !== ZodParsedType.nan) {
addIssueToContext(ctx, {
code: ZodIssueCode.invalid_type,
expected: ZodParsedType.nan,
received: ctx.parsedType,
});
return INVALID;
}

return { status: status.value, value: ctx.data };
}

static create = (params?: RawCreateParams): ZodNaN => {
return new ZodNaN({
typeName: ZodFirstPartyTypeKind.ZodNaN,
...processCreateParams(params),
});
};
}

export const custom = <T>(
check?: (data: unknown) => any,
params?: Parameters<ZodTypeAny["refine"]>[1]
Expand All @@ -3451,6 +3486,7 @@ export const late = {
export enum ZodFirstPartyTypeKind {
ZodString = "ZodString",
ZodNumber = "ZodNumber",
ZodNaN = "ZodNaN",
ZodBigInt = "ZodBigInt",
ZodBoolean = "ZodBoolean",
ZodDate = "ZodDate",
Expand Down Expand Up @@ -3483,6 +3519,7 @@ export enum ZodFirstPartyTypeKind {
export type ZodFirstPartySchemaTypes =
| ZodString
| ZodNumber
| ZodNaN
| ZodBigInt
| ZodBoolean
| ZodDate
Expand Down Expand Up @@ -3520,6 +3557,7 @@ const instanceOfType = <T extends new (...args: any[]) => any>(

const stringType = ZodString.create;
const numberType = ZodNumber.create;
const nanType = ZodNaN.create;
const bigIntType = ZodBigInt.create;
const booleanType = ZodBoolean.create;
const dateType = ZodDate.create;
Expand Down Expand Up @@ -3568,6 +3606,7 @@ export {
lazyType as lazy,
literalType as literal,
mapType as map,
nanType as nan,
nativeEnumType as nativeEnum,
neverType as never,
nullType as null,
Expand Down

0 comments on commit 4a549b1

Please sign in to comment.