Projections
On this page
Occasionally, you may need to derive a new schema from an existing one, specifically targeting either its Type
or Encoded
portion. The @effect/schema
library provides several APIs to support this functionality.
typeSchema
The Schema.typeSchema
function allows you to extract the Type
portion of a schema, creating a new schema that conforms to the properties defined in the original schema without considering the initial encoding or transformation processes.
Function Signature
ts
declare const typeSchema: <A, I, R>(schema: Schema<A, I, R>) => Schema<A>
ts
declare const typeSchema: <A, I, R>(schema: Schema<A, I, R>) => Schema<A>
Example
ts
import {Schema } from "@effect/schema"constoriginal =Schema .Struct ({foo :Schema .NumberFromString .pipe (Schema .greaterThanOrEqualTo (2))})// This creates a schema where 'foo' is strictly a number// that must be greater than or equal to 2.constresultingTypeSchema =Schema .typeSchema (original )// resultingTypeSchema is the same as:constresultingTypeSchema2 =Schema .Struct ({foo :Schema .Number .pipe (Schema .greaterThanOrEqualTo (2))})
ts
import {Schema } from "@effect/schema"constoriginal =Schema .Struct ({foo :Schema .NumberFromString .pipe (Schema .greaterThanOrEqualTo (2))})// This creates a schema where 'foo' is strictly a number// that must be greater than or equal to 2.constresultingTypeSchema =Schema .typeSchema (original )// resultingTypeSchema is the same as:constresultingTypeSchema2 =Schema .Struct ({foo :Schema .Number .pipe (Schema .greaterThanOrEqualTo (2))})
In this example:
- Original Schema: The schema for
foo
is initially defined to accept a number from a string and enforce that it is greater than or equal to 2. - Resulting Type Schema: The
Schema.typeSchema
function extracts only the type-related information fromfoo
, simplifying it to just a number while still maintaining the constraint that it must be greater than or equal to 2.
encodedSchema
The Schema.encodedSchema
function allows you to extract the Encoded
portion of a schema,
creating a new schema that conforms to the properties defined in the original schema without retaining any refinements or transformations that were applied previously.
Function Signature
ts
declare const encodedSchema: <A, I, R>(schema: Schema<A, I, R>) => Schema<I>
ts
declare const encodedSchema: <A, I, R>(schema: Schema<A, I, R>) => Schema<I>
Example
ts
import {Schema } from "@effect/schema"constoriginal =Schema .Struct ({foo :Schema .String .pipe (Schema .minLength (3))})// resultingEncodedSchema simplifies 'foo' to just a string,// disregarding the minLength refinement.constresultingEncodedSchema =Schema .encodedSchema (original )// resultingEncodedSchema is the same as:constresultingEncodedSchema2 =Schema .Struct ({foo :Schema .String })
ts
import {Schema } from "@effect/schema"constoriginal =Schema .Struct ({foo :Schema .String .pipe (Schema .minLength (3))})// resultingEncodedSchema simplifies 'foo' to just a string,// disregarding the minLength refinement.constresultingEncodedSchema =Schema .encodedSchema (original )// resultingEncodedSchema is the same as:constresultingEncodedSchema2 =Schema .Struct ({foo :Schema .String })
In this example:
- Original Schema Definition: The
foo
field in the schema is defined as a string with a minimum length of three characters. - Resulting Encoded Schema: The
encodedSchema
function simplifies thefoo
field to just a string type, effectively stripping away theminLength
refinement.
encodedBoundSchema
The Schema.encodedBoundSchema
function is similar to Schema.encodedSchema
but preserves the refinements up to the first transformation point in the
original schema.
Function Signature
ts
declare const encodedBoundSchema: <A, I, R>(schema: Schema<A, I, R>) => Schema<I>
ts
declare const encodedBoundSchema: <A, I, R>(schema: Schema<A, I, R>) => Schema<I>
The term "bound" in this context refers to the boundary up to which refinements are preserved when extracting the encoded form of a schema. It essentially marks the limit to which initial validations and structure are maintained before any transformations are applied.
Example
ts
import {Schema } from "@effect/schema"constoriginal =Schema .Struct ({foo :Schema .String .pipe (Schema .minLength (3),Schema .compose (Schema .Trim ))})// The resultingEncodedBoundSchema preserves the minLength(3) refinement,// ensuring the string length condition is enforced but omits the Trim transformation.constresultingEncodedBoundSchema =Schema .encodedBoundSchema (original )// resultingEncodedBoundSchema is the same as:constresultingEncodedBoundSchema2 =Schema .Struct ({foo :Schema .String .pipe (Schema .minLength (3))})
ts
import {Schema } from "@effect/schema"constoriginal =Schema .Struct ({foo :Schema .String .pipe (Schema .minLength (3),Schema .compose (Schema .Trim ))})// The resultingEncodedBoundSchema preserves the minLength(3) refinement,// ensuring the string length condition is enforced but omits the Trim transformation.constresultingEncodedBoundSchema =Schema .encodedBoundSchema (original )// resultingEncodedBoundSchema is the same as:constresultingEncodedBoundSchema2 =Schema .Struct ({foo :Schema .String .pipe (Schema .minLength (3))})
In the provided example:
- Initial Schema: The schema for
foo
includes a refinement to ensure strings have a minimum length of three characters and a transformation to trim the string. - Resulting Schema:
resultingEncodedBoundSchema
maintains theSchema.minLength(3)
condition, ensuring that this validation persists. However, it excludes the trimming transformation, focusing solely on the length requirement without altering the string's formatting.