API reference@evolu/commonType › transform

Call Signature

function transform<Name, ParentType, OutputType, ToOutput>(
  name: ValidateChildTypeName<Name, ParentType>,
  parent: ValidateParent<ParentType>,
  output: ValidateOutput<OutputType>,
  operations: {
    from: (value: ParentType["Output"]) => Result<OutputType["Input"], never>;
    to: (value: CanonicalInputOf<OutputType>) => ToOutput;
  },
): TransformType<ParentType, OutputType, Name, never, ToOutput>;

Defined in: packages/common/src/Type.ts:2277

Transform Type.

from accepts the semantic Output. from.parent converts the parent Output to the output Type Input, then runs the complete output Type pipeline. to canonically encodes every output Type value before converting it back through the parent Type.

The callbacks must form a lawful codec: decoding to(output) must reproduce the same semantic Output for every valid output value. Encoding may canonicalize multiple parent representations, but it must be total and must not lose distinctions present in the Output domain.

Transformation callbacks are Type construction code. Their successful results are asserted against the declared boundary so a broken callback fails as a developer error rather than becoming a validation error. Like all Type-construction callbacks, they are trusted to follow their declared TypeScript types. A Result<_, never> callback is therefore trusted never to return an Err.

Errors from the parent and the forward callback remain unchanged. A forward callback error must use the transformation name as its type. Errors from the output Type are nested in a TransformOutputError so formatting can be delegated to that particular Type, so outputError is reserved for that wrapper. When the forward callback is fallible, the final formatter argument formats only that callback's own errors. Parent and output Type errors use their respective formatters automatically.

Example

import {
  assertEqual,
  assertOk,
  Boolean,
  literal,
  ok,
  transform,
  union,
} from "@evolu/common";

const BooleanString = union(literal("false"), literal("true"));
const BooleanFromString = transform(
  "BooleanFromString",
  BooleanString,
  Boolean,
  {
    from: (value) => ok(value === "true"),
    to: (value) => (value ? "true" : "false"),
  },
);

assertOk(BooleanFromString.from.parent("true"), true);
assertEqual(BooleanFromString.to(false), "false");

Call Signature

function transform<Name, ParentType, OutputType, ToOutput, FromError>(
  name: ValidateChildTypeName<Name, ParentType>,
  parent: ValidateParent<ParentType>,
  output: ValidateOutput<OutputType>,
  operations: {
    from: (
      value: ParentType["Output"],
    ) => Result<OutputType["Input"], FromError>;
    to: (value: CanonicalInputOf<OutputType>) => ToOutput;
  },
  formatError: [FromError] extends [never]
    ? never
    : TypeErrorFormatter<NoInfer>,
): TransformType<ParentType, OutputType, Name, FromError, ToOutput>;

Defined in: packages/common/src/Type.ts:2349

Creates a fallible transformed Type with its own error formatter.

Example

import {
  assertEqual,
  assertType,
  Data,
  assertErr,
  assertOk,
  Boolean,
  String,
  err,
  ok,
  transform,
  type Result,
  type TypeError,
} from "@evolu/common";

interface BooleanFromStringError extends TypeError<"BooleanFromString"> {
  readonly value: string;
}

const BooleanFromString = transform(
  "BooleanFromString",
  String,
  Boolean,
  {
    from: (value): Result<boolean, BooleanFromStringError> =>
      value === "true"
        ? ok(true)
        : value === "false"
          ? ok(false)
          : err({ type: "BooleanFromString", value }),
    to: (value) => (value ? "true" : "false"),
  },
  () => 'Expected "true" or "false".',
);

assertOk(BooleanFromString.fromUnknown("true"), true);
assertEqual(BooleanFromString.to(false), "false");

const invalid = BooleanFromString.fromUnknown("yes");
assertErr(invalid);
assertType(Data, invalid.error);
assertEqual(invalid.error, { type: "BooleanFromString", value: "yes" });
assertEqual(
  BooleanFromString.formatError(invalid.error),
  'Expected "true" or "false".',
);