diff --git a/.changeset/nasty-vans-tan.md b/.changeset/nasty-vans-tan.md new file mode 100644 index 000000000..095a241e9 --- /dev/null +++ b/.changeset/nasty-vans-tan.md @@ -0,0 +1,5 @@ +--- +"@effect/schema": patch +--- + +add `never` handling to struct API diff --git a/docs/modules/Schema.ts.md b/docs/modules/Schema.ts.md index aa4fc97f3..e61de00f1 100644 --- a/docs/modules/Schema.ts.md +++ b/docs/modules/Schema.ts.md @@ -40,6 +40,8 @@ Added in v1.0.0 - [nonNegativeBigint](#nonnegativebigint) - [nonPositiveBigint](#nonpositivebigint) - [positiveBigint](#positivebigint) +- [boolean](#boolean) + - [not](#not) - [combinators](#combinators) - [annotations](#annotations-1) - [array](#array-1) @@ -139,7 +141,7 @@ Added in v1.0.0 - [primitives](#primitives) - [any](#any) - [bigint](#bigint-1) - - [boolean](#boolean) + - [boolean](#boolean-1) - [never](#never) - [null](#null) - [number](#number-1) @@ -519,6 +521,20 @@ export declare const positiveBigint: ( Added in v1.0.0 +# boolean + +## not + +Negates a boolean value + +**Signature** + +```ts +export declare const not: (self: Schema) => Schema +``` + +Added in v1.0.0 + # combinators ## annotations @@ -930,7 +946,13 @@ Added in v1.0.0 ```ts export declare const struct: < - Fields extends Record | PropertySignature> + Fields extends Record< + string | number | symbol, + | Schema + | Schema + | PropertySignature + | PropertySignature + > >( fields: Fields ) => Schema< @@ -2299,7 +2321,11 @@ Added in v1.0.0 ```ts export type OptionalKeys = { - [K in keyof Fields]: Fields[K] extends PropertySignature ? K : never + [K in keyof Fields]: Fields[K] extends + | PropertySignature + | PropertySignature + ? K + : never }[keyof Fields] ``` @@ -2310,7 +2336,7 @@ Added in v1.0.0 **Signature** ```ts -export interface PropertySignature { +export interface PropertySignature { readonly From: (_: From) => From readonly To: (_: To) => To readonly ToIsOptional: ToIsOptional diff --git a/dtslint/ts4.9/Schema.ts b/dtslint/ts4.9/Schema.ts index 2726c4ec3..dff6828cc 100644 --- a/dtslint/ts4.9/Schema.ts +++ b/dtslint/ts4.9/Schema.ts @@ -234,6 +234,9 @@ export type MyModelFrom = S.From // $ExpectType { readonly a: string; readonly b: number; } export type MyModelTo = S.To +// $ExpectType Schema<{ readonly a: never; }, { readonly a: never; }> +S.struct({ a: S.never }) + // --------------------------------------------- // optional // --------------------------------------------- @@ -248,6 +251,9 @@ S.struct({ a: S.string, b: S.number, c: S.optional(NumberFromString) }); // $ExpectType Schema<{ readonly a?: string; }, { readonly a?: string; }> S.struct({ a: pipe(S.string, S.optional) }) +// $ExpectType Schema<{ readonly a?: never; }, { readonly a?: never; }> + S.struct({ a: S.optional(S.never) }) + // --------------------------------------------- // optional.withDefault // --------------------------------------------- diff --git a/src/Schema.ts b/src/Schema.ts index a4eafa95a..12d100dc5 100644 --- a/src/Schema.ts +++ b/src/Schema.ts @@ -461,7 +461,7 @@ export type PropertySignatureId = typeof PropertySignatureId /** * @since 1.0.0 */ -export interface PropertySignature { +export interface PropertySignature { readonly From: (_: From) => From readonly To: (_: To) => To readonly ToIsOptional: ToIsOptional @@ -504,7 +504,8 @@ optional.withDefault = dual(2, (schema, value) => _optional(schema, { to: "defau * @since 1.0.0 */ export type OptionalKeys = { - [K in keyof Fields]: Fields[K] extends PropertySignature ? K + [K in keyof Fields]: Fields[K] extends + PropertySignature | PropertySignature ? K : never }[keyof Fields] @@ -513,7 +514,13 @@ export type OptionalKeys = { * @since 1.0.0 */ export const struct = < - Fields extends Record | PropertySignature> + Fields extends Record< + PropertyKey, + | Schema + | Schema + | PropertySignature + | PropertySignature + > >( fields: Fields ): Schema< diff --git a/test/optional.ts b/test/optional.ts index 446a8fc9b..f575f9feb 100644 --- a/test/optional.ts +++ b/test/optional.ts @@ -25,6 +25,12 @@ describe.concurrent("optional", () => { await Util.expectEncodeSuccess(schema, { a: O.none() }, {}) }) + it("never", async () => { + const schema = S.struct({ a: S.optional(S.never), b: S.number }) + await Util.expectParseSuccess(schema, { b: 1 }) + await Util.expectParseFailure(schema, { a: "a", b: 1 }, `/a Expected never, actual "a"`) + }) + it("all", async () => { const schema = S.struct({ a: S.boolean,