API reference › @evolu/common › Type › createType
Call Signature
function createType<Name, Output, Error>(
name: ValidateConcreteTypeName<Name>,
fromUnknown: (value: unknown) => Result<Output, Error>,
formatError: TypeErrorFormatter<NoInfer>,
): Type<Name, Output, Output, Error, null, Error, never, Output>;
Defined in: packages/common/src/Type.ts:1972
Custom Type.
createType is refinement-only. Use transform to change a value's
representation. On success, a validation callback must return the value it
received, narrowed to its output type, rather than a replacement value. This
includes replacements assignable to the same TypeScript type. The
identity-preserving contract is asserted at runtime. It lets structural Types
preserve their input values and makes encoding an identity step.
Like all Type-construction callbacks, validation callbacks are trusted to
follow their declared TypeScript types. A Result<_, never> callback is
therefore trusted never to return an Err.
An infallible child accepts every parent Output, so its Output remains the parent Output. A fallible child can narrow that Output but cannot change its representation.
A root formatter handles the root validation error. A child formatter handles
only the error introduced by that child; inherited errors are formatted by
the parent Type automatically. A fallible child must have one concrete name;
its error's type must equal that name and must not duplicate an inherited
error type. An infallible child has no own error to format.
Example
A root Type for a custom external value category:
import {
assertEqual,
assertErr,
assertOk,
assertType,
createType,
Data,
err,
ok,
type Result,
type TypeError,
} from "@evolu/common";
interface TextError extends TypeError<"Text"> {
readonly value: unknown;
}
const Text = createType(
"Text",
(value): Result<string, TextError> =>
typeof value === "string" ? ok(value) : err({ type: "Text", value }),
() => "Expected text.",
);
assertOk(Text.fromUnknown("Evolu"), "Evolu");
const invalid = Text.fromUnknown(42);
assertErr(invalid);
assertType(Data, invalid.error);
assertEqual(invalid.error, { type: "Text", value: 42 });
Call Signature
function createType<Name, ParentType>(
name: ValidateConcreteTypeName<Name>,
parent: ValidateParent<ParentType>,
fromParent: (
value: ParentType["Output"],
) => Result<ParentType["Output"], never>,
): Type<
Name,
ParentType["Input"],
ParentType["Output"],
never,
ParentType,
InferErrors<ParentType>,
ChildCustomFrom<ParentType, ParentType["Output"], never>,
CanonicalInputForChild<ParentType, ParentType["Output"]>,
IdentityEncodingOf<ParentType>
>;
Defined in: packages/common/src/Type.ts:1984
Creates an infallible child Type that preserves its parent's Output.
Call Signature
function createType<Name, ParentType, Output, Error>(
name: Name,
parent: ValidateBrandParent<Name, ParentType>,
fromParent: (value: ParentType["Output"]) => Result<Output, Error>,
formatError: [Error] extends [never] ? never : TypeErrorFormatter<NoInfer>,
): Type<
Name,
ParentType["Input"],
Output,
Error,
ParentType,
Error | InferErrors<ParentType>,
ChildCustomFrom<ParentType, Output, Error>,
CanonicalInputForChild<ParentType, Output>,
IdentityEncodingOf<ParentType>
>;
Defined in: packages/common/src/Type.ts:2007
Creates a fallible child Type that narrows its parent's Output.