fromFormData<S>Schema for decoding FormData through a bracket-notation tree.
When to use
Use to decode browser or multipart form data into a structured schema value.
Details
The decoding process has two steps:
- Parse
FormDatainto a nested tree record. - Decode the parsed value with the given schema.
You can express nested values using bracket notation.
If you want to decode string fields into non-string primitive values, use
Schema.toCodecStringTree.
Example (Decoding a flat structure)
import { Schema } from "effect"
const schema = Schema.fromFormData(
Schema.Struct({
a: Schema.String
})
)
const formData = new FormData()
formData.append("a", "1")
formData.append("b", "2")
console.log(String(Schema.decodeUnknownExit(schema)(formData)))
// Success({"a":"1"})Example (Decoding nested fields)
import { Schema } from "effect"
const schema = Schema.fromFormData(
Schema.Struct({
a: Schema.String,
b: Schema.Struct({
c: Schema.String,
d: Schema.String
})
})
)
const formData = new FormData()
formData.append("a", "1")
formData.append("b[c]", "2")
formData.append("b[d]", "3")
console.log(String(Schema.decodeUnknownExit(schema)(formData)))
// Success({"a":"1","b":{"c":"2","d":"3"}})Example (Parsing non-string values)
import { Schema } from "effect"
const schema = Schema.fromFormData(
Schema.toCodecStringTree(
Schema.Struct({
a: Schema.Int
})
)
)
const formData = new FormData()
formData.append("a", "1")
console.log(String(Schema.decodeUnknownExit(schema)(formData)))
// Success({"a":1}) // Note: the value is a numberexport interface interface fromFormData<S extends Constraint>Schema for decoding FormData through a bracket-notation tree.
When to use
Use to decode browser or multipart form data into a structured schema value.
Details
The decoding process has two steps:
- Parse
FormData into a nested tree record.
- Decode the parsed value with the given schema.
You can express nested values using bracket notation.
If you want to decode string fields into non-string primitive values, use
Schema.toCodecStringTree.
Example (Decoding a flat structure)
import { Schema } from "effect"
const schema = Schema.fromFormData(
Schema.Struct({
a: Schema.String
})
)
const formData = new FormData()
formData.append("a", "1")
formData.append("b", "2")
console.log(String(Schema.decodeUnknownExit(schema)(formData)))
// Success({"a":"1"})
Example (Decoding nested fields)
import { Schema } from "effect"
const schema = Schema.fromFormData(
Schema.Struct({
a: Schema.String,
b: Schema.Struct({
c: Schema.String,
d: Schema.String
})
})
)
const formData = new FormData()
formData.append("a", "1")
formData.append("b[c]", "2")
formData.append("b[d]", "3")
console.log(String(Schema.decodeUnknownExit(schema)(formData)))
// Success({"a":"1","b":{"c":"2","d":"3"}})
Example (Parsing non-string values)
import { Schema } from "effect"
const schema = Schema.fromFormData(
Schema.toCodecStringTree(
Schema.Struct({
a: Schema.Int
})
)
)
const formData = new FormData()
formData.append("a", "1")
console.log(String(Schema.decodeUnknownExit(schema)(formData)))
// Success({"a":1}) // Note: the value is a number
Type-level representation returned by
fromFormData
.
fromFormData<function (type parameter) S in fromFormData<S extends Constraint>S extends Constraint> extends interface decodeTo<To extends Constraint, From extends Constraint, RD = never, RE = never>Creates a schema that transforms from a source schema to a target schema.
When to use
Use when decoding should change the schema's decoded type or encoded shape,
with an optional custom bidirectional transformation.
Details
Call it with the target schema to and then pipe the source schema from
into the returned function. The resulting schema decodes from
From["Encoded"] to To["Type"] and encodes from To["Type"] back to
From["Encoded"].
When no transformation is provided, SchemaTransformation.passthrough() is
used, so From["Type"] must already be compatible with To["Encoded"].
The resulting schema combines decoding and encoding services from both
schemas and any custom transformation.
Gotchas
In a custom transformation, decode maps From["Type"] to To["Encoded"]
and is used on the encoding path, while encode maps To["Encoded"] to
From["Type"] and is used on the decoding path.
Example (Transforming strings to numbers with a schema transformation)
import { Schema, SchemaGetter } from "effect"
const NumberFromString = Schema.String.pipe(
Schema.decodeTo(
Schema.Number,
{
decode: SchemaGetter.transform((s) => Number(s)),
encode: SchemaGetter.transform((n) => String(n))
}
)
)
const result = Schema.decodeUnknownSync(NumberFromString)("123")
// result: 123
Type-level representation returned by
decodeTo
.
decodeTo<function (type parameter) S in fromFormData<S extends Constraint>S, FormData> {
readonly "Rebuild": interface fromFormData<S extends Constraint>Schema for decoding FormData through a bracket-notation tree.
When to use
Use to decode browser or multipart form data into a structured schema value.
Details
The decoding process has two steps:
- Parse
FormData into a nested tree record.
- Decode the parsed value with the given schema.
You can express nested values using bracket notation.
If you want to decode string fields into non-string primitive values, use
Schema.toCodecStringTree.
Example (Decoding a flat structure)
import { Schema } from "effect"
const schema = Schema.fromFormData(
Schema.Struct({
a: Schema.String
})
)
const formData = new FormData()
formData.append("a", "1")
formData.append("b", "2")
console.log(String(Schema.decodeUnknownExit(schema)(formData)))
// Success({"a":"1"})
Example (Decoding nested fields)
import { Schema } from "effect"
const schema = Schema.fromFormData(
Schema.Struct({
a: Schema.String,
b: Schema.Struct({
c: Schema.String,
d: Schema.String
})
})
)
const formData = new FormData()
formData.append("a", "1")
formData.append("b[c]", "2")
formData.append("b[d]", "3")
console.log(String(Schema.decodeUnknownExit(schema)(formData)))
// Success({"a":"1","b":{"c":"2","d":"3"}})
Example (Parsing non-string values)
import { Schema } from "effect"
const schema = Schema.fromFormData(
Schema.toCodecStringTree(
Schema.Struct({
a: Schema.Int
})
)
)
const formData = new FormData()
formData.append("a", "1")
console.log(String(Schema.decodeUnknownExit(schema)(formData)))
// Success({"a":1}) // Note: the value is a number
Type-level representation returned by
fromFormData
.
fromFormData<function (type parameter) S in fromFormData<S extends Constraint>S>
}
/**
* Schema for decoding `FormData` through a bracket-notation tree.
*
* **When to use**
*
* Use to decode browser or multipart form data into a structured schema value.
*
* **Details**
*
* The decoding process has two steps:
*
* 1. Parse `FormData` into a nested tree record.
* 2. Decode the parsed value with the given schema.
*
* You can express nested values using bracket notation.
*
* If you want to decode string fields into non-string primitive values, use
* `Schema.toCodecStringTree`.
*
* **Example** (Decoding a flat structure)
*
* ```ts
* import { Schema } from "effect"
*
* const schema = Schema.fromFormData(
* Schema.Struct({
* a: Schema.String
* })
* )
*
* const formData = new FormData()
* formData.append("a", "1")
* formData.append("b", "2")
*
* console.log(String(Schema.decodeUnknownExit(schema)(formData)))
* // Success({"a":"1"})
* ```
*
* **Example** (Decoding nested fields)
*
* ```ts
* import { Schema } from "effect"
*
* const schema = Schema.fromFormData(
* Schema.Struct({
* a: Schema.String,
* b: Schema.Struct({
* c: Schema.String,
* d: Schema.String
* })
* })
* )
*
* const formData = new FormData()
* formData.append("a", "1")
* formData.append("b[c]", "2")
* formData.append("b[d]", "3")
*
* console.log(String(Schema.decodeUnknownExit(schema)(formData)))
* // Success({"a":"1","b":{"c":"2","d":"3"}})
* ```
*
* **Example** (Parsing non-string values)
*
* ```ts
* import { Schema } from "effect"
*
* const schema = Schema.fromFormData(
* Schema.toCodecStringTree(
* Schema.Struct({
* a: Schema.Int
* })
* )
* )
*
* const formData = new FormData()
* formData.append("a", "1")
*
* console.log(String(Schema.decodeUnknownExit(schema)(formData)))
* // Success({"a":1}) // Note: the value is a number
* ```
*
* @category decoding
* @since 4.0.0
*/
export function function fromFormData<
S extends Constraint
>(schema: S): fromFormData<S>
Schema for decoding FormData through a bracket-notation tree.
When to use
Use to decode browser or multipart form data into a structured schema value.
Details
The decoding process has two steps:
- Parse
FormData into a nested tree record.
- Decode the parsed value with the given schema.
You can express nested values using bracket notation.
If you want to decode string fields into non-string primitive values, use
Schema.toCodecStringTree.
Example (Decoding a flat structure)
import { Schema } from "effect"
const schema = Schema.fromFormData(
Schema.Struct({
a: Schema.String
})
)
const formData = new FormData()
formData.append("a", "1")
formData.append("b", "2")
console.log(String(Schema.decodeUnknownExit(schema)(formData)))
// Success({"a":"1"})
Example (Decoding nested fields)
import { Schema } from "effect"
const schema = Schema.fromFormData(
Schema.Struct({
a: Schema.String,
b: Schema.Struct({
c: Schema.String,
d: Schema.String
})
})
)
const formData = new FormData()
formData.append("a", "1")
formData.append("b[c]", "2")
formData.append("b[d]", "3")
console.log(String(Schema.decodeUnknownExit(schema)(formData)))
// Success({"a":"1","b":{"c":"2","d":"3"}})
Example (Parsing non-string values)
import { Schema } from "effect"
const schema = Schema.fromFormData(
Schema.toCodecStringTree(
Schema.Struct({
a: Schema.Int
})
)
)
const formData = new FormData()
formData.append("a", "1")
console.log(String(Schema.decodeUnknownExit(schema)(formData)))
// Success({"a":1}) // Note: the value is a number
fromFormData<function (type parameter) S in fromFormData<S extends Constraint>(schema: S): fromFormData<S>S extends Constraint>(schema: S extends Constraintschema: function (type parameter) S in fromFormData<S extends Constraint>(schema: S): fromFormData<S>S): interface fromFormData<S extends Constraint>Schema for decoding FormData through a bracket-notation tree.
When to use
Use to decode browser or multipart form data into a structured schema value.
Details
The decoding process has two steps:
- Parse
FormData into a nested tree record.
- Decode the parsed value with the given schema.
You can express nested values using bracket notation.
If you want to decode string fields into non-string primitive values, use
Schema.toCodecStringTree.
Example (Decoding a flat structure)
import { Schema } from "effect"
const schema = Schema.fromFormData(
Schema.Struct({
a: Schema.String
})
)
const formData = new FormData()
formData.append("a", "1")
formData.append("b", "2")
console.log(String(Schema.decodeUnknownExit(schema)(formData)))
// Success({"a":"1"})
Example (Decoding nested fields)
import { Schema } from "effect"
const schema = Schema.fromFormData(
Schema.Struct({
a: Schema.String,
b: Schema.Struct({
c: Schema.String,
d: Schema.String
})
})
)
const formData = new FormData()
formData.append("a", "1")
formData.append("b[c]", "2")
formData.append("b[d]", "3")
console.log(String(Schema.decodeUnknownExit(schema)(formData)))
// Success({"a":"1","b":{"c":"2","d":"3"}})
Example (Parsing non-string values)
import { Schema } from "effect"
const schema = Schema.fromFormData(
Schema.toCodecStringTree(
Schema.Struct({
a: Schema.Int
})
)
)
const formData = new FormData()
formData.append("a", "1")
console.log(String(Schema.decodeUnknownExit(schema)(formData)))
// Success({"a":1}) // Note: the value is a number
Type-level representation returned by
fromFormData
.
fromFormData<function (type parameter) S in fromFormData<S extends Constraint>(schema: S): fromFormData<S>S> {
return const FormData: FormDataconst FormData: {
Rebuild: FormData;
Iso: Iso;
ast: Ast;
Type: T;
Encoded: E;
DecodingServices: RD;
EncodingServices: RE;
annotate: (annotations: Annotations.Bottom<globalThis.FormData, readonly []>) => FormData;
annotateKey: (annotations: Annotations.Key<globalThis.FormData>) => FormData;
check: (checks_0: SchemaAST.Check<globalThis.FormData>, ...checks: Array<SchemaAST.Check<globalThis.FormData>>) => FormData;
rebuild: (ast: SchemaAST.Declaration) => FormData;
make: (input: globalThis.FormData, options?: MakeOptions) => globalThis.FormData;
makeOption: (input: globalThis.FormData, options?: MakeOptions) => Option_.Option<globalThis.FormData>;
makeEffect: (input: globalThis.FormData, options?: MakeOptions) => Effect.Effect<globalThis.FormData, SchemaError, never>;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
}
Type-level representation of
FormData
.
Schema for JavaScript FormData objects.
Details
The default JSON serializer encodes a FormData as an array of [key, entry]
pairs where each entry is tagged as "String" or "File".
FormData.pipe(function decodeTo<S, Constraint, never, never>(to: S, transformation: {
readonly decode: SchemaGetter.Getter<NoInfer<S["Encoded"]>, unknown, never>;
readonly encode: SchemaGetter.Getter<unknown, NoInfer<S["Encoded"]>, never>;
}): (from: Constraint) => decodeTo<S, Constraint, never, never> (+1 overload)
Creates a schema that transforms from a source schema to a target schema.
When to use
Use when decoding should change the schema's decoded type or encoded shape,
with an optional custom bidirectional transformation.
Details
Call it with the target schema to and then pipe the source schema from
into the returned function. The resulting schema decodes from
From["Encoded"] to To["Type"] and encodes from To["Type"] back to
From["Encoded"].
When no transformation is provided, SchemaTransformation.passthrough() is
used, so From["Type"] must already be compatible with To["Encoded"].
The resulting schema combines decoding and encoding services from both
schemas and any custom transformation.
Gotchas
In a custom transformation, decode maps From["Type"] to To["Encoded"]
and is used on the encoding path, while encode maps To["Encoded"] to
From["Type"] and is used on the decoding path.
Example (Transforming strings to numbers with a schema transformation)
import { Schema, SchemaGetter } from "effect"
const NumberFromString = Schema.String.pipe(
Schema.decodeTo(
Schema.Number,
{
decode: SchemaGetter.transform((s) => Number(s)),
encode: SchemaGetter.transform((n) => String(n))
}
)
)
const result = Schema.decodeUnknownSync(NumberFromString)("123")
// result: 123
decodeTo(schema: S extends Constraintschema, import SchemaTransformationSchemaTransformation.const fromFormData: SchemaTransformation.Transformation<
unknown,
globalThis.FormData,
never,
never
>
const fromFormData: {
_tag: 'Transformation';
decode: SchemaGetter.Getter<T, E, RD>;
encode: SchemaGetter.Getter<E, T, RE>;
flip: () => SchemaTransformation.Transformation<globalThis.FormData, unknown, never, never>;
compose: (other: SchemaTransformation.Transformation<T2, unknown, RD2, RE2>) => SchemaTransformation.Transformation<T2, globalThis.FormData, RD2, RE2>;
}
Decodes a FormData instance into a nested record using bracket-path keys and
encodes object-like values back into FormData.
When to use
Use when you need a schema transformation for form or multipart payloads
whose keys, such as user[name] or items[0], should become nested data.
Details
Decode preserves string and Blob leaves. Encode flattens nested objects and
arrays into bracket-path entries and returns an empty FormData for
non-object inputs.
Example (Decoding FormData)
import { Schema, SchemaTransformation } from "effect"
const schema = Schema.instanceOf(FormData).pipe(
Schema.decodeTo(Schema.Unknown, SchemaTransformation.fromFormData)
)
fromFormData))
}