Skip to main content Link Search Menu Expand Document (external link)

InputError.ts overview

Tagged error type for input-validation failures, paired with constructors that build the error message and assertion helpers that lift those constructors into Result-returning predicates.

Mental model

  • Type is a Data.TaggedError whose only field is a human-readable message.
  • For each validation scenario this module exports two functions:

    • A constructor (e.g. wrongValue, missized) that builds an InputError with a pre-formatted message;
    • An assertion (e.g. assertValue, assertLength) that returns a curried predicate (input) => Result.Result<input, Type> using that constructor on failure.
  • All name-bearing inputs default the prefix of the message to "value" when omitted.

Common tasks

  • Validate equality: assertValue (and constructor wrongValue)
  • Validate length: assertLength, assertMaxLength (constructors missized, oversized)
  • Validate range: assertInRange (constructor outOfBounds)
  • Validate strings: assertStartsWith, assertMatches, match, assertEmpty (constructors notStartingWith, notMatching, notEmpty)

Quickstart

Example (Validate a value)

import { Result, pipe } from "effect"
import * as MInputError from "@parischap/effect-lib/MInputError"

console.log(pipe("admin", MInputError.assertValue({ expected: "admin", name: "role" })))
// Success('admin')

console.log(pipe("user", MInputError.assertValue({ expected: "admin", name: "role" })))
// Failure(InputError("Expected role to be: 'admin'. Actual: 'user'"))

Exports Grouped by Category


Constructors

missized

Builds an InputError for an array-like value whose length differs from the expected one.

See

  • assertLength — assertion-style counterpart

Signature

declare const missized: ({
  expected,
  actual,
  name
}: {
  readonly expected: number
  readonly actual: number
  readonly name?: string
}) => Type

Source

notEmpty

Builds an InputError for a string that should have been empty.

See

  • assertEmpty — assertion-style counterpart

Signature

declare const notEmpty: ({ actual, name }: { readonly actual: string; readonly name?: string }) => Type

Source

notMatching

Builds an InputError for a string that does not match a given regular expression.

  • regExpDescriptor is the human-readable description used in the error message (e.g. "a valid email").

See

  • assertMatches — assertion-style counterpart

Signature

declare const notMatching: ({
  regExpDescriptor,
  actual,
  name
}: {
  readonly regExpDescriptor: string
  readonly actual: string
  readonly name?: string
}) => Type

Source

notStartingWith

Builds an InputError for a string that does not start with startString.

See

  • assertStartsWith — assertion-style counterpart

Signature

declare const notStartingWith: ({
  startString,
  actual,
  name
}: {
  readonly startString: string
  readonly actual: string
  readonly name?: string
}) => Type

Source

outOfBounds

Builds an InputError for a numeric value that fell outside [min, max].

  • minIncluded / maxIncluded control whether the corresponding bound is inclusive.
  • offset is added to min, max and actual only when formatting the message — it is purely cosmetic and lets callers report bounds in a different unit (e.g. 1-based indexing).

See

  • assertInRange — assertion-style counterpart

Signature

declare const outOfBounds: ({
  min,
  max,
  minIncluded,
  maxIncluded,
  offset,
  actual,
  name
}: {
  readonly min: number
  readonly max: number
  readonly minIncluded: boolean
  readonly maxIncluded: boolean
  readonly offset: number
  readonly actual: number
  readonly name?: string
}) => Type

Source

oversized

Builds an InputError for an array-like value whose length exceeds the expected upper bound.

See

  • assertMaxLength — assertion-style counterpart

Signature

declare const oversized: ({
  expected,
  actual,
  name
}: {
  readonly expected: number
  readonly actual: number
  readonly name?: string
}) => Type

Source

wrongValue

Builds an InputError for a value that did not match the expected one.

  • String operands are quoted with single quotes in the message; other primitives are stringified with toString.
  • name defaults to "value" when omitted.

Example (Manual error construction)

import * as MInputError from "@parischap/effect-lib/MInputError"

console.log(MInputError.wrongValue({ expected: "admin", actual: "user", name: "role" }).message)
// "Expected role to be: 'admin'. Actual: 'user'"

See

  • assertValue — assertion-style counterpart

Signature

declare const wrongValue: <T extends MTypes.NonNullablePrimitive>({
  expected,
  actual,
  name
}: {
  readonly expected: T
  readonly actual: T
  readonly name?: string
}) => Type

Source

Models

Type (class)

Tagged error returned by every assertion in this module.

Signature

declare class Type

Source

Module markers

moduleTag

Module tag.

Signature

declare const moduleTag: "@parischap/effect-lib/InputError/"

Source

Utils

assertEmpty

Asserts that input is the empty string.

  • Returns a notEmpty error on failure.

Example (Empty check)

import { pipe } from "effect"
import * as MInputError from "@parischap/effect-lib/MInputError"

console.log(pipe("", MInputError.assertEmpty())) // Success('')
console.log(pipe("x", MInputError.assertEmpty())) // Failure(InputError(...))

Signature

declare const assertEmpty: (params?: {
  readonly name?: string
}) => MTypes.OneArgFunction<string, Result.Result<string, Type>>

Source

assertInRange

Asserts that input lies in the interval [min, max], with each bound inclusive or exclusive according to minIncluded / maxIncluded.

  • Returns an outOfBounds error on failure.

Example (Range check)

import { pipe } from "effect"
import * as MInputError from "@parischap/effect-lib/MInputError"

const isPercentage = MInputError.assertInRange({
  min: 0,
  max: 100,
  minIncluded: true,
  maxIncluded: true,
  offset: 0,
  name: "percentage"
})
console.log(pipe(50, isPercentage)) // Success(50)
console.log(pipe(150, isPercentage)) // Failure(InputError(...))

Signature

declare const assertInRange: (params: {
  readonly min: number
  readonly max: number
  readonly minIncluded: boolean
  readonly maxIncluded: boolean
  readonly offset: number
  readonly name?: string
}) => MTypes.OneArgFunction<number, Result.Result<number, Type>>

Source

assertLength

Asserts that input.length === expected.

  • Works with any ArrayLike<unknown> or string.
  • Returns a missized error on failure.

Example (Length check)

import { pipe } from "effect"
import * as MInputError from "@parischap/effect-lib/MInputError"

console.log(pipe("abc", MInputError.assertLength({ expected: 3 }))) // Success('abc')
console.log(pipe("abcd", MInputError.assertLength({ expected: 3 }))) // Failure(InputError(...))

Signature

declare const assertLength: (params: {
  readonly expected: number
  readonly name?: string
}) => <A extends ArrayLike<unknown> | string>(self: A) => Result.Result<A, Type>

Source

assertMatches

Asserts that input matches regExp.

  • Returns the matched input on success, a notMatching error on failure.

Example (Regex check)

import { pipe } from "effect"
import * as MInputError from "@parischap/effect-lib/MInputError"

console.log(pipe("hello", MInputError.assertMatches({ regExp: /^[a-z]+$/, regExpDescriptor: "lowercase letters" })))
// Success('hello')

See

  • match — variant returning the matched substring

Signature

declare const assertMatches: (params: {
  readonly regExp: RegExp
  readonly regExpDescriptor: string
  readonly name?: string
}) => MTypes.OneArgFunction<string, Result.Result<string, Type>>

Source

assertMaxLength

Asserts that input.length <= expected.

  • Works with any ArrayLike<unknown> or string.
  • Returns an oversized error on failure.

Example (Maximum length check)

import { pipe } from "effect"
import * as MInputError from "@parischap/effect-lib/MInputError"

const within10 = MInputError.assertMaxLength({ expected: 10 })
console.log(pipe("hello", within10)) // Success('hello')
console.log(pipe("hello world!", within10)) // Failure(InputError(...))

Signature

declare const assertMaxLength: (params: {
  readonly expected: number
  readonly name?: string
}) => <A extends ArrayLike<unknown> | string>(self: A) => Result.Result<A, Type>

Source

assertStartsWith

Asserts that input starts with startString.

  • Returns a notStartingWith error on failure.

Example (Prefix check)

import { pipe } from "effect"
import * as MInputError from "@parischap/effect-lib/MInputError"

console.log(pipe("hello world", MInputError.assertStartsWith({ startString: "hello" })))
// Success('hello world')

Signature

declare const assertStartsWith: (params: {
  readonly startString: string
  readonly name?: string
}) => MTypes.OneArgFunction<string, Result.Result<string, Type>>

Source

assertValue

Asserts that input === expected (using strict equality).

  • Returns Result.success(input) when the equality holds, otherwise Result.failure with a wrongValue error.

Example (Equality check)

import { pipe } from "effect"
import * as MInputError from "@parischap/effect-lib/MInputError"

const isAdmin = MInputError.assertValue({ expected: "admin", name: "role" })

console.log(pipe("admin", isAdmin)) // Success('admin')
console.log(pipe("user", isAdmin)) // Failure(InputError(...))

Signature

declare const assertValue: <T extends MTypes.NonNullablePrimitive>(params: {
  readonly expected: NoInfer<T>
  readonly name?: string
}) => MTypes.OneArgFunction<T, Result.Result<T, Type>>

Source

match

Returns the substring of input matching regExp. Returns a notMatching error when input does not match.

  • Differs from assertMatches in that the success value is the matched substring, not the whole input.

Example (Extract first match)

import { pipe } from "effect"
import * as MInputError from "@parischap/effect-lib/MInputError"

console.log(pipe("abc123", MInputError.match({ regExp: /\d+/, regExpDescriptor: "digits" })))
// Success('123')

See

  • assertMatches — variant preserving the original input on success

Signature

declare const match: (params: {
  readonly regExp: RegExp
  readonly regExpDescriptor: string
  readonly name?: string
}) => (self: string) => Result.Result<string, Type>

Source