API reference / @evolu/common / Type / createFormatTypeError

Function: createFormatTypeError()

function createFormatTypeError<ExtraErrors>(
  extraFormatter?,
): TypeErrorFormatter<TypeErrors<ExtraErrors>>;

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

Formats Evolu Type errors into user-friendly messages.

Evolu Type typed errors ensure every error type must have a formatter. TypeScript enforces this at compile-time, preventing unhandled validation errors from reaching users.

The createFormatTypeError function handles both built-in TypeErrors and custom errors, and lets us override default formatting for specific errors.

Example

const formatTypeError = createFormatTypeError<MinLengthError | MaxLengthError>(
  (error): string => {
    switch (error.type) {
      case "MinLength":
        return `Text must be at least ${error.min} character${error.min === 1 ? "" : "s"} long`;
      case "MaxLength":
        return `Text is too long (maximum ${error.max} characters)`;
    }
  },
);

Alternatively, write a custom formatter from scratch without using createFormatTypeError. This gives us full control over error formatting:

const Person = object({
  name: NonEmptyTrimmedString100,
  age: optional(PositiveInt),
});

// Define only the errors actually used by Person Type
type PersonErrors =
  | StringError
  | MaxLengthError
  | MinLengthError
  | TrimmedError
  | PositiveError
  | NonNegativeError
  | IntError
  | NumberError
  | ObjectError<Record<string, PersonErrors>>;

const formatTypeError: TypeErrorFormatter<PersonErrors> = (error) => {
  switch (error.type) {
    case "String":
      return formatStringError(error);
    case "Number":
      return "Must be a number";
    case "MinLength":
      return `Must be at least ${error.min} characters`;
    case "MaxLength":
      return `Cannot exceed ${error.max} characters`;
    case "Trimmed":
      return "Cannot have leading or trailing spaces";
    case "Positive":
      return "Must be a positive number";
    case "NonNegative":
      return "Must be zero or positive";
    case "Int":
      return "Must be an integer";
    case "Object": {
      if (error.reason.kind === "NotObject") return "Must be an object";
      if (error.reason.kind === "ExtraKeys")
        return "Contains unexpected fields";
      const firstError = Object.values(error.reason.errors).find(
        (e) => e !== undefined,
      )!;
      return formatTypeError(firstError);
    }
  }
};

Type Parameters

Type ParameterDefault type
ExtraErrors extends TypeError<Capitalize<string>>never

Parameters

ParameterType
extraFormatter?TypeErrorFormatter<ExtraErrors>

Returns

TypeErrorFormatter<TypeErrors<ExtraErrors>>

Was this page helpful?