Skip to content

VariantSchema.ts

Builds related schemas for named variants from shared field definitions.

make fixes the variant names and default variant, then lets callers define fields that are shared by all variants or specific to some variants. From those definitions it can create schema classes, unions, extracted struct schemas, and helpers for changing fields across variants.

Since v4.0.0



Returns the original field definitions stored on a variant schema struct.

Signature

declare const fields: <A extends Struct<any>>(self: A) => A[typeof TypeId]

Source

Since v4.0.0

Creates a variant schema toolkit for a fixed set of variant names and a default variant.

Signature

declare const make: <const Variants extends ReadonlyArray<string>, const Default extends Variants[number]>(options: {
readonly variants: Variants
readonly defaultVariant: Default
}) => {
readonly Struct: <const A extends Struct.Fields>(fields: A & Struct.Validate<A, Variants[number]>) => Struct<A>
readonly Field: <const A extends Field.ConfigWithKeys<Variants[number]>>(
config: A & { readonly [K in Exclude<keyof A, Variants[number]>]: never }
) => Field<A>
readonly FieldOnly: <const Keys extends ReadonlyArray<Variants[number]>>(
keys: Keys
) => <S extends Schema.Top>(schema: S) => Field<{ readonly [K in Keys[number]]: S }>
readonly FieldExcept: <const Keys extends ReadonlyArray<Variants[number]>>(
keys: Keys
) => <S extends Schema.Top>(schema: S) => Field<{ readonly [K in Exclude<Variants[number], Keys[number]>]: S }>
readonly fieldEvolve: {
<
Self extends Field<any> | Schema.Top,
const Mapping extends Self extends Field<infer S>
? { readonly [K in keyof S]?: (variant: S[K]) => Schema.Top }
: { readonly [K in Variants[number]]?: (variant: Self) => Schema.Top }
>(
f: Mapping
): (
self: Self
) => Field<
Self extends Field<infer S>
? {
readonly [K in keyof S]: K extends keyof Mapping
? Mapping[K] extends (arg: any) => any
? ReturnType<Mapping[K]>
: S[K]
: S[K]
}
: {
readonly [K in Variants[number]]: K extends keyof Mapping
? Mapping[K] extends (arg: any) => any
? ReturnType<Mapping[K]>
: Self
: Self
}
>
<
Self extends Field<any> | Schema.Top,
const Mapping extends Self extends Field<infer S>
? { readonly [K in keyof S]?: (variant: S[K]) => Schema.Top }
: { readonly [K in Variants[number]]?: (variant: Self) => Schema.Top }
>(
self: Self,
f: Mapping
): Field<
Self extends Field<infer S>
? {
readonly [K in keyof S]: K extends keyof Mapping
? Mapping[K] extends (arg: any) => any
? ReturnType<Mapping[K]>
: S[K]
: S[K]
}
: {
readonly [K in Variants[number]]: K extends keyof Mapping
? Mapping[K] extends (arg: any) => any
? ReturnType<Mapping[K]>
: Self
: Self
}
>
}
readonly Class: <Self = never>(
identifier: string
) => <const Fields extends Struct.Fields>(
fields: Fields & Struct.Validate<Fields, Variants[number]>,
annotations?:
| Schema.Annotations.Declaration<Self, readonly [Schema.Struct<ExtractFields<Default, Fields, true>>]>
| undefined
) => [Self] extends [never]
? MissingSelfGeneric
: Class<Self, Fields, Schema.Struct<ExtractFields<Default, Fields, true>>> & {
readonly [V in Variants[number]]: Extract<V, Struct<Fields>>
}
readonly Union: <const Members extends ReadonlyArray<Struct<any>>>(
members: Members
) => Union<Members> & Union.Variants<Members, Variants[number]>
readonly extract: {
<V extends Variants[number]>(
variant: V
): <A extends Struct<any>>(self: A) => Extract<V, A, V extends Default ? true : false>
<V extends Variants[number], A extends Struct<any>>(
self: A,
variant: V
): Extract<V, A, V extends Default ? true : false>
}
}

Source

Since v4.0.0

Computes the schema type produced by extracting a single variant from a variant schema struct.

Signature

type Extract<V, A, IsDefault> = [A] extends [Struct<infer Fields>]
? IsDefault extends true
? [A] extends [Schema.Top]
? A
: Schema.Struct<Struct_.Simplify<ExtractFields<V, Fields>>>
: Schema.Struct<Struct_.Simplify<ExtractFields<V, Fields>>>
: never

Source

Since v4.0.0

Computes the Schema.Struct field map for a variant by selecting matching field schemas and recursively extracting nested structs.

Signature

type ExtractFields<V, Fields, IsDefault> = {
readonly [K in keyof Fields as [Fields[K]] extends [Field<infer Config>]
? V extends keyof Config
? K
: never
: K]: [Fields[K]] extends [Struct<infer _>]
? Extract<V, Fields[K], IsDefault>
: [Fields[K]] extends [Field<infer Config>]
? [Config[V]] extends [Schema.Top]
? Config[V]
: never
: [Fields[K]] extends [Schema.Top]
? Fields[K]
: never
}

Source

Since v4.0.0

Returns true when a value is a variant schema field.

Signature

declare const isField: (u: unknown) => u is Field<any>

Source

Since v4.0.0

Returns true when a value is a variant schema struct.

Signature

declare const isStruct: (u: unknown) => u is Struct<any>

Source

Since v4.0.0

Schema class type returned by variant class constructors, combining the default variant schema with access to the original variant fields.

Signature

export interface Class<
Self,
Fields extends Struct.Fields,
S extends Schema.Top & {
readonly fields: Schema.Struct.Fields
}
>
extends
Schema.BottomLazy<
SchemaAST.Declaration,
Schema.decodeTo<Schema.declareConstructor<Self, S["Encoded"], readonly [S], S["Iso"]>, S>,
readonly [S],
S["~type.mutability"],
S["~type.optionality"],
S["~type.constructor.default"],
S["~encoded.mutability"],
S["~encoded.optionality"]
>,
Struct<Struct_.Simplify<Fields>> {
readonly Type: Self
readonly Encoded: S["Encoded"]
readonly DecodingServices: S["DecodingServices"]
readonly EncodingServices: S["EncodingServices"]
readonly "~type.make.in": S["~type.make.in"]
readonly "~type.make": Self
readonly Iso: S["Iso"]
new (
props: S["~type.make.in"],
options?:
| {
readonly disableChecks?: boolean
}
| undefined
): S["Type"]
make<Args extends Array<any>, X>(this: { new (...args: Args): X }, ...args: Args): X
readonly fields: S["fields"]
}

Source

Since v4.0.0

Pipeable collection of variant-specific schemas for a single logical field.

Signature

export interface Field<in out A extends Field.Config> extends Pipeable {
readonly [FieldTypeId]: typeof FieldTypeId
readonly schemas: A
}

Source

Since v4.0.0

Pipeable container of schema fields that can be extracted into per-variant Schema.Struct schemas.

Signature

export interface Struct<in out A extends Field.Fields> extends Pipeable {
readonly [TypeId]: A
/** @internal */
[cacheSymbol]?: Record<string, Schema.Top>
}

Source

Since v4.0.0

Union schema over the default schemas of a list of variant schema structs.

Signature

export interface Union<Members extends ReadonlyArray<Struct<any>>> extends Schema.Union<{
readonly [K in keyof Members]: [Members[K]] extends [Schema.Top] ? Members[K] : never
}> {}

Source

Since v4.0.0

Marks a value as an explicit override for an Overrideable schema default.

Signature

declare const Override: <A>(value: A) => A & Brand<"Override">

Source

Since v4.0.0

Wraps a schema with an effectful constructor default while allowing explicit values to be marked with Override.

Signature

declare const Overrideable: <S extends Schema.Top & Schema.WithoutConstructorDefault>(
schema: S,
options: { readonly defaultValue: Effect.Effect<S["~type.make.in"]> }
) => Overrideable<S>

Source

Since v4.0.0

Schema type whose constructor can use an effectful default unless a value is explicitly branded with Override.

Signature

export interface Overrideable<S extends Schema.Top & Schema.WithoutConstructorDefault> extends Schema.BottomLazy<
S["ast"],
Overrideable<S>,
S["~type.parameters"],
S["~type.mutability"],
"required",
"with-default",
S["~encoded.mutability"],
S["~encoded.optionality"]
> {
readonly Type: S["Type"] & Brand<"Override">
readonly Encoded: S["Encoded"]
readonly DecodingServices: S["DecodingServices"]
readonly EncodingServices: S["EncodingServices"]
readonly "~type.make.in": S["~type.make.in"]
readonly "~type.make": (S["Type"] & Brand<"Override">) | undefined
readonly Iso: (S["Type"] & Brand<"Override">) | undefined
}

Source

Since v4.0.0

Runtime type identifier attached to variant schema structs.

Signature

declare const TypeId: "~effect/schema/VariantSchema"

Source

Since v4.0.0

Type-level helpers for variant schema fields.

Source

Since v4.0.0

Minimal structural type for any variant schema field.

Signature

type Any = { readonly [FieldTypeId]: typeof FieldTypeId }

Source

Since v4.0.0

Map from variant name to the schema used for a field in that variant.

Signature

type Config = {
readonly [key: string]: Schema.Top | undefined
}

Source

Since v4.0.0

Variant field configuration restricted to an optional subset of the supplied variant keys.

Signature

type ConfigWithKeys<K> = {
readonly [P in K]?: Schema.Top
}

Source

Since v4.0.0

Field map whose properties may be schemas, variant fields, nested structs, or undefined.

Signature

type Fields = {
readonly [key: string]: Schema.Top | Field<any> | Struct<any> | undefined
}

Source

Since v4.0.0

Type-level helpers for variant schema structs.

Source

Since v4.0.0

Minimal structural type for any variant schema struct.

Signature

type Any = { readonly [TypeId]: any }

Source

Since v4.0.0

Field map accepted by a variant struct, where each property may be a schema, a variant field, a nested struct, or undefined.

Signature

type Fields = {
readonly [key: string]: Schema.Top | Field<any> | Struct<any> | undefined
}

Source

Since v4.0.0

Type-level validation that every variant field in a struct only uses variants from the configured variant set.

Signature

type Validate<A, Variant> = {
readonly [K in keyof A]: A[K] extends { readonly [TypeId]: infer _ }
? Validate<A[K], Variant>
: A[K] extends Field<infer Config>
? [keyof Config] extends [Variant]
? {}
: "field must have valid variants"
: {}
}

Source

Since v4.0.0

Type-level helpers for unions of variant schema structs.

Source

Since v4.0.0

Computes a union schema for each variant from a list of variant schema structs.

Signature

type Union.Variants<Members, Variants> = {
readonly [Variant in Variants]: Schema.Union<
{
[K in keyof Members]: Extract<Variant, Members[K]>
}
>
}

Source

Since v4.0.0