From 8ec49555ed3b3c98093fa4d135a4c57a3f16ebd1 Mon Sep 17 00:00:00 2001 From: Giulio Canti Date: Wed, 17 Jul 2024 19:28:01 +0200 Subject: [PATCH] remove type-level error message from `optional` signature, closes #3290 (#3291) --- .changeset/moody-maps-agree.md | 7 +++++++ packages/schema/dtslint/Schema.ts | 16 +++++++++++++--- packages/schema/src/Schema.ts | 5 +---- 3 files changed, 21 insertions(+), 7 deletions(-) create mode 100644 .changeset/moody-maps-agree.md diff --git a/.changeset/moody-maps-agree.md b/.changeset/moody-maps-agree.md new file mode 100644 index 0000000000..71a56e527c --- /dev/null +++ b/.changeset/moody-maps-agree.md @@ -0,0 +1,7 @@ +--- +"@effect/schema": patch +--- + +remove type-level error message from `optional` signature, closes #3290 + +This fix eliminates the type-level error message from the `optional` function signature, which was causing issues in generic contexts. diff --git a/packages/schema/dtslint/Schema.ts b/packages/schema/dtslint/Schema.ts index 1a35cf19ee..cac0889c2f 100644 --- a/packages/schema/dtslint/Schema.ts +++ b/packages/schema/dtslint/Schema.ts @@ -523,9 +523,6 @@ S.Struct({ a: S.String.pipe(S.optional({ exact: true })) }) // optional - Errors // --------------------------------------------- -// @ts-expect-error -S.Boolean.pipe(S.optional) - // @ts-expect-error S.optional(S.String, { as: "Option", default: () => "" }) @@ -559,6 +556,19 @@ S.optional(S.String, { as: null }) // @ts-expect-error S.optional(S.String, { default: null }) +// --------------------------------------------- +// optional() used in a generic context +// --------------------------------------------- + +type TypeWithValue = { value: S.optionalWithOptions } + +const makeTypeWithValue = (value: Value): TypeWithValue => ({ + value: S.optional(value, { nullable: true }) +}) + +// $ExpectType TypeWithValue +makeTypeWithValue(S.String) + // --------------------------------------------- // optional() // --------------------------------------------- diff --git a/packages/schema/src/Schema.ts b/packages/schema/src/Schema.ts index 5593a914b1..c4a4a2fb94 100644 --- a/packages/schema/src/Schema.ts +++ b/packages/schema/src/Schema.ts @@ -2243,13 +2243,10 @@ export const optional: { options?: Options ): (self: S) => [undefined] extends [Options] ? optional : optionalWithOptions >>( - self: Schema.All extends S ? "you can't apply optional implicitly, use optional() instead" : S, + self: S, options?: Options ): [undefined] extends [Options] ? optional : optionalWithOptions } = dual((args) => isSchema(args[0]), (from, options) => { - // Note: `Schema.All extends S ? "you can't...` is used to prevent the case where `optional` is implicitly applied. - // For example: `S.String.pipe(S.optional)` would result in `S.String` being inferred as `Schema.All`, - // which is not the intended behavior. This is mostly an aesthetic consideration, so if it causes issues, we can remove it. return new PropertySignatureWithFromImpl(optionalPropertySignatureAST(from, options), from) })