Skip to content

Commit

Permalink
feat: Allow passing custom message to literal
Browse files Browse the repository at this point in the history
Fixes #2974

Uses a message key instead of "invalid_xx" key - because those are only used for required and invalid type
using a message key is more in line with other checks
  • Loading branch information
LiamMartens committed Nov 18, 2023
1 parent c4458ca commit 41ce771
Show file tree
Hide file tree
Showing 4 changed files with 50 additions and 2 deletions.
21 changes: 21 additions & 0 deletions deno/lib/__tests__/literal.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ const test = Deno.test;
import * as z from "../index.ts";

const literalTuna = z.literal("tuna");
const literalTunaCustomMessage = z.literal("tuna", {
message: "That's not a tuna",
});
const literalFortyTwo = z.literal(42);
const literalTrue = z.literal(true);

Expand Down Expand Up @@ -35,3 +38,21 @@ test("invalid_literal should have `received` field with data", () => {
}
}
});

test("invalid_literal should return default message", () => {
const data = "shark";
const result = literalTuna.safeParse(data);
if (!result.success) {
const issue = result.error.issues[0];
expect(issue.message).toEqual(`Invalid literal value, expected \"tuna\"`);
}
});

test("invalid_literal should return custom message", () => {
const data = "shark";
const result = literalTunaCustomMessage.safeParse(data);
if (!result.success) {
const issue = result.error.issues[0];
expect(issue.message).toEqual(`That's not a tuna`);
}
});
5 changes: 4 additions & 1 deletion deno/lib/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3913,6 +3913,7 @@ export class ZodLazy<T extends ZodTypeAny> extends ZodType<
export interface ZodLiteralDef<T = any> extends ZodTypeDef {
value: T;
typeName: ZodFirstPartyTypeKind.ZodLiteral;
message?: string;
}

export class ZodLiteral<T> extends ZodType<T, ZodLiteralDef<T>> {
Expand All @@ -3923,6 +3924,7 @@ export class ZodLiteral<T> extends ZodType<T, ZodLiteralDef<T>> {
received: ctx.data,
code: ZodIssueCode.invalid_literal,
expected: this._def.value,
message: this._def.message,
});
return INVALID;
}
Expand All @@ -3935,11 +3937,12 @@ export class ZodLiteral<T> extends ZodType<T, ZodLiteralDef<T>> {

static create = <T extends Primitive>(
value: T,
params?: RawCreateParams
params?: RawCreateParams & Exclude<errorUtil.ErrMessage, string>
): ZodLiteral<T> => {
return new ZodLiteral({
value: value,
typeName: ZodFirstPartyTypeKind.ZodLiteral,
message: params?.message,
...processCreateParams(params),
});
};
Expand Down
21 changes: 21 additions & 0 deletions src/__tests__/literal.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ import { expect, test } from "@jest/globals";
import * as z from "../index";

const literalTuna = z.literal("tuna");
const literalTunaCustomMessage = z.literal("tuna", {
message: "That's not a tuna",
});
const literalFortyTwo = z.literal(42);
const literalTrue = z.literal(true);

Expand Down Expand Up @@ -34,3 +37,21 @@ test("invalid_literal should have `received` field with data", () => {
}
}
});

test("invalid_literal should return default message", () => {
const data = "shark";
const result = literalTuna.safeParse(data);
if (!result.success) {
const issue = result.error.issues[0];
expect(issue.message).toEqual(`Invalid literal value, expected \"tuna\"`);
}
});

test("invalid_literal should return custom message", () => {
const data = "shark";
const result = literalTunaCustomMessage.safeParse(data);
if (!result.success) {
const issue = result.error.issues[0];
expect(issue.message).toEqual(`That's not a tuna`);
}
});
5 changes: 4 additions & 1 deletion src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3913,6 +3913,7 @@ export class ZodLazy<T extends ZodTypeAny> extends ZodType<
export interface ZodLiteralDef<T = any> extends ZodTypeDef {
value: T;
typeName: ZodFirstPartyTypeKind.ZodLiteral;
message?: string;
}

export class ZodLiteral<T> extends ZodType<T, ZodLiteralDef<T>> {
Expand All @@ -3923,6 +3924,7 @@ export class ZodLiteral<T> extends ZodType<T, ZodLiteralDef<T>> {
received: ctx.data,
code: ZodIssueCode.invalid_literal,
expected: this._def.value,
message: this._def.message,
});
return INVALID;
}
Expand All @@ -3935,11 +3937,12 @@ export class ZodLiteral<T> extends ZodType<T, ZodLiteralDef<T>> {

static create = <T extends Primitive>(
value: T,
params?: RawCreateParams
params?: RawCreateParams & Exclude<errorUtil.ErrMessage, string>
): ZodLiteral<T> => {
return new ZodLiteral({
value: value,
typeName: ZodFirstPartyTypeKind.ZodLiteral,
message: params?.message,
...processCreateParams(params),
});
};
Expand Down

0 comments on commit 41ce771

Please sign in to comment.