From 723496096414285a9b04da6285fa0ffe560380b0 Mon Sep 17 00:00:00 2001 From: gcanti Date: Fri, 16 Feb 2024 18:01:15 +0100 Subject: [PATCH] Schema: change the `MessageAnnotation` type to be non-parametric; now it's simply `(u: unknown) => string` to accommodate custom error messages, which can be triggered by any circumstances --- .changeset/gentle-hounds-juggle.md | 5 +++++ packages/schema/src/AST.ts | 4 ++-- packages/schema/src/Schema.ts | 4 ++-- packages/schema/test/Schema/filter.test.ts | 9 ++++++++- 4 files changed, 17 insertions(+), 5 deletions(-) create mode 100644 .changeset/gentle-hounds-juggle.md diff --git a/.changeset/gentle-hounds-juggle.md b/.changeset/gentle-hounds-juggle.md new file mode 100644 index 0000000000..cb2b684208 --- /dev/null +++ b/.changeset/gentle-hounds-juggle.md @@ -0,0 +1,5 @@ +--- +"@effect/schema": minor +--- + +Change the `MessageAnnotation` type to be non-parametric; now it's simply `(u: unknown) => string` to accommodate custom error messages, which can be triggered by any circumstances diff --git a/packages/schema/src/AST.ts b/packages/schema/src/AST.ts index c8b7908d9b..912d4f3066 100644 --- a/packages/schema/src/AST.ts +++ b/packages/schema/src/AST.ts @@ -46,7 +46,7 @@ export const TypeAnnotationId = Symbol.for("@effect/schema/annotation/Type") * @category annotations * @since 1.0.0 */ -export type MessageAnnotation = (a: A) => string +export type MessageAnnotation = (u: unknown) => string /** * @category annotations @@ -173,7 +173,7 @@ export const getAnnotation: { * @category annotations * @since 1.0.0 */ -export const getMessageAnnotation = getAnnotation>( +export const getMessageAnnotation = getAnnotation( MessageAnnotationId ) diff --git a/packages/schema/src/Schema.ts b/packages/schema/src/Schema.ts index 6651d4d287..27a385908d 100644 --- a/packages/schema/src/Schema.ts +++ b/packages/schema/src/Schema.ts @@ -517,7 +517,7 @@ const declarePrimitive = ( * @since 1.0.0 */ export interface DeclareAnnotations

, A> extends DocAnnotations { - readonly message?: AST.MessageAnnotation + readonly message?: AST.MessageAnnotation readonly typeId?: AST.TypeAnnotation | { id: AST.TypeAnnotation; annotation: unknown } readonly arbitrary?: (...arbitraries: { readonly [K in keyof P]: Arbitrary }) => Arbitrary readonly pretty?: (...pretties: { readonly [K in keyof P]: Pretty.Pretty }) => Pretty.Pretty @@ -1909,7 +1909,7 @@ export const annotations = (annotations: AST.Annotations) => (self: Sch * @category annotations * @since 1.0.0 */ -export const message = (message: AST.MessageAnnotation) => (self: Schema): Schema => +export const message = (message: AST.MessageAnnotation) => (self: Schema): Schema => make(AST.setAnnotation(self.ast, AST.MessageAnnotationId, message)) /** diff --git a/packages/schema/test/Schema/filter.test.ts b/packages/schema/test/Schema/filter.test.ts index ced54f012a..8edb234ae8 100644 --- a/packages/schema/test/Schema/filter.test.ts +++ b/packages/schema/test/Schema/filter.test.ts @@ -6,7 +6,7 @@ import * as Option from "effect/Option" import { describe, expect, it } from "vitest" describe("Schema > filter", () => { - it("filter/ annotation options", () => { + it("annotation options", () => { const schema = S.string.pipe( S.filter((s): s is string => s.length === 1, { typeId: Symbol.for("Char"), @@ -58,4 +58,11 @@ describe("Schema > filter", () => { └─ b should be equal to a's value ("a")` ) }) + + it("custom message", async () => { + const schema = S.string.pipe(S.filter((s): s is string => s.length === 1, { + message: (u) => `invalid ${u}` + })) + await Util.expectDecodeUnknownFailure(schema, null, `invalid null`) + }) })