@effect/schema
Advanced tools
Comparing version 0.33.0 to 0.33.1
{ | ||
"name": "@effect/schema", | ||
"version": "0.33.0", | ||
"version": "0.33.1", | ||
"description": "Modeling the schema of data structures as first-class values", | ||
@@ -5,0 +5,0 @@ "license": "MIT", |
100
README.md
@@ -913,2 +913,89 @@ <h3 align="center"> | ||
## Classes | ||
As an alternative to the `struct` constructor, you can create schemas as classes by extending the `Class` utility. | ||
They offer a few conveniences that can help with some common use cases: | ||
- define a schema and an opaque type in one pass | ||
- attach common functionality using class methods or getters | ||
- check equality by value and hashing (`Class` implements `Data.Case`) | ||
Take a look at the following example: | ||
```ts | ||
import * as S from "@effect/schema/Schema"; | ||
// Define your schema by extending `Class` with the desired fields | ||
class Person extends S.Class({ | ||
id: S.number, | ||
name: S.string | ||
}) { | ||
// Add getters and methods | ||
get upperName() { | ||
return this.name.toUpperCase(); | ||
} | ||
} | ||
// Extend an existing schema `Class` using the `extend` utility | ||
class PersonWithAge extends Person.extend({ | ||
age: S.number | ||
}) { | ||
get isAdult() { | ||
return this.age >= 18; | ||
} | ||
} | ||
// You can use the class constructor to validate and then create a new instance from some properties | ||
const tim = new Person({ id: 1, name: "Tim" }); | ||
// $ExpectType Schema<{ readonly id: number; name: string; }, Person> | ||
Person.schema(); | ||
// $ExpectType Schema<{ readonly id: number; name: string; }, { readonly id: number; name: string; }> | ||
Person.schemaStruct(); | ||
``` | ||
#### Transforms | ||
You can enhance a class with (effectful) transforms. This can be useful if you want to embellish or validate an entity from a data store. | ||
```ts | ||
import * as Effect from "@effect/io/Effect"; | ||
import * as S from "@effect/schema/Schema"; | ||
import * as O from "@effect/data/Option"; | ||
import * as PR from "@effect/schema/ParseResult"; | ||
class Person extends S.Class({ | ||
id: S.number, | ||
name: S.string | ||
}) | ||
function fetchThing(id: number): Effect.Effect<never, Error, string> { ... } | ||
class PersonWithTransform extends Person.transform( | ||
{ | ||
thing: S.optional(S.string).toOption(), | ||
}, | ||
(input) => | ||
Effect.mapBoth(fetchThing(input.id), { | ||
onFailure: (e) => PR.parseError([PR.type(S.string, input, e.message)]), | ||
onSuccess: (thing) => ({ ...input, thing: O.some(thing) }) | ||
}), | ||
PR.success | ||
) {} | ||
class PersonWithTransformFrom extends Person.transformFrom( | ||
{ | ||
thing: S.optional(S.string).toOption(), | ||
}, | ||
(input) => | ||
Effect.mapBoth(fetchThing(input.id), { | ||
onFailure: (e) => PR.parseError([PR.type(S.string, input, e.message)]), | ||
onSuccess: (thing) => ({ ...input, thing }) | ||
}), | ||
PR.success | ||
) {} | ||
``` | ||
## Pick | ||
@@ -1127,4 +1214,2 @@ | ||
import * as Effect from "@effect/io/Effect"; | ||
import fetch from "node-fetch"; | ||
import { pipe } from "@effect/data/Function"; | ||
import * as TF from "@effect/schema/TreeFormatter"; | ||
@@ -1150,7 +1235,6 @@ | ||
(s) => | ||
Effect.mapBoth( | ||
api(`https://swapi.dev/api/people/${s}`), | ||
(e) => PR.parseError([PR.type(PeopleId.ast, s, e.message)]), | ||
() => s | ||
), | ||
Effect.mapBoth(api(`https://swapi.dev/api/people/${s}`), { | ||
onFailure: (e) => PR.parseError([PR.type(PeopleId.ast, s, e.message)]), | ||
onSuccess: () => s | ||
}), | ||
PR.success | ||
@@ -1160,3 +1244,3 @@ ); | ||
const parse = (id: string) => | ||
Effect.mapError(S.parseEffect(PeopleIdFromString)(id), (e) => | ||
Effect.mapError(S.parse(PeopleIdFromString)(id), (e) => | ||
TF.formatErrors(e.errors) | ||
@@ -1163,0 +1247,0 @@ ); |
@@ -317,6 +317,26 @@ /** | ||
/** | ||
* @since 1.0.0 | ||
*/ | ||
export type StructFields = Record<PropertyKey, Schema<any> | Schema<never> | PropertySignature<any, boolean, any, boolean> | PropertySignature<never, boolean, never, boolean>>; | ||
/** | ||
* @since 1.0.0 | ||
*/ | ||
export type FromStruct<Fields extends StructFields> = { | ||
readonly [K in Exclude<keyof Fields, FromOptionalKeys<Fields>>]: From<Fields[K]>; | ||
} & { | ||
readonly [K in FromOptionalKeys<Fields>]?: From<Fields[K]>; | ||
}; | ||
/** | ||
* @since 1.0.0 | ||
*/ | ||
export type ToStruct<Fields extends StructFields> = { | ||
readonly [K in Exclude<keyof Fields, ToOptionalKeys<Fields>>]: To<Fields[K]>; | ||
} & { | ||
readonly [K in ToOptionalKeys<Fields>]?: To<Fields[K]>; | ||
}; | ||
/** | ||
* @category combinators | ||
* @since 1.0.0 | ||
*/ | ||
export declare const struct: <Fields extends Record<PropertyKey, Schema<any, any> | Schema<never, never> | PropertySignature<any, boolean, any, boolean> | PropertySignature<never, boolean, never, boolean>>>(fields: Fields) => Schema<Spread<{ readonly [K in Exclude<keyof Fields, FromOptionalKeys<Fields>>]: From<Fields[K]>; } & { readonly [K_1 in FromOptionalKeys<Fields>]?: From<Fields[K_1]>; }>, Spread<{ readonly [K_2 in Exclude<keyof Fields, ToOptionalKeys<Fields>>]: To<Fields[K_2]>; } & { readonly [K_3 in ToOptionalKeys<Fields>]?: To<Fields[K_3]>; }>>; | ||
export declare const struct: <Fields extends StructFields>(fields: Fields) => Schema<Spread<FromStruct<Fields>>, Spread<ToStruct<Fields>>>; | ||
/** | ||
@@ -504,2 +524,32 @@ * @category combinators | ||
export declare const documentation: (documentation: AST.DocumentationAnnotation) => <I, A>(self: Schema<I, A>) => Schema<I, A>; | ||
/** | ||
* @category classes | ||
* @since 1.0.0 | ||
*/ | ||
export interface Class<I, A, Inherited = {}> { | ||
new (props: A): A & D.Case & Omit<Inherited, keyof A>; | ||
schema<T extends new (...args: any) => any>(this: T): Schema<I, InstanceType<T>>; | ||
schemaStruct(): Schema<I, A>; | ||
extend<T extends new (...args: any) => any, Fields extends StructFields>(this: T, fields: Fields): Class<Spread<Omit<Class.From<T>, keyof Fields> & FromStruct<Fields>>, Spread<Omit<Class.To<T>, keyof Fields> & ToStruct<Fields>>, InstanceType<T>>; | ||
transform<T extends new (...args: any) => any, Fields extends StructFields>(this: T, fields: Fields, decode: (input: Class.To<T>) => ParseResult<Omit<Class.To<T>, keyof Fields> & ToStruct<Fields>>, encode: (input: Omit<Class.To<T>, keyof Fields> & ToStruct<Fields>) => ParseResult<Class.To<T>>): Class<Class.From<T>, Spread<Omit<Class.To<T>, keyof Fields> & ToStruct<Fields>>, InstanceType<T>>; | ||
transformFrom<T extends new (...args: any) => any, Fields extends StructFields>(this: T, fields: Fields, decode: (input: Class.From<T>) => ParseResult<Omit<Class.From<T>, keyof Fields> & FromStruct<Fields>>, encode: (input: Omit<Class.From<T>, keyof Fields> & FromStruct<Fields>) => ParseResult<Class.From<T>>): Class<Class.From<T>, Spread<Omit<Class.To<T>, keyof Fields> & ToStruct<Fields>>, InstanceType<T>>; | ||
} | ||
/** | ||
* @since 1.0.0 | ||
*/ | ||
export declare namespace Class { | ||
/** | ||
* @since 1.0.0 | ||
*/ | ||
type To<A> = A extends Class<infer _F, infer T> ? T : never; | ||
/** | ||
* @since 1.0.0 | ||
*/ | ||
type From<A> = A extends Class<infer F, infer _T> ? F : never; | ||
} | ||
/** | ||
* @category classes | ||
* @since 1.0.0 | ||
*/ | ||
export declare const Class: <Fields extends StructFields>(fields: Fields) => Class<Spread<FromStruct<Fields>>, Spread<ToStruct<Fields>>, {}>; | ||
declare const _undefined: Schema<undefined>; | ||
@@ -506,0 +556,0 @@ declare const _void: Schema<void>; |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
948723
17913
1762