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

Predicate.ts overview

Extension to the effect/Predicate module providing type-level utilities for predicates and refinements, an enhanced struct predicate, a strict-equality predicate constructor, and runtime guards for the container/primitive shapes defined in MTypes.

Mental model

  • Predicate.Predicate<A> is a function (a: A) => boolean.
  • Predicate.Refinement<A, B> is a predicate that narrows A to B when it returns true.
  • This module focuses on type-level introspection (Source, Target, Coverage), value-level constructors (strictEquals, struct), and runtime guards for the container shapes declared in MTypes (OverOne, OverTwo, Singleton, Pair, plus primitive vs non-primitive splits and function arity).

Common tasks

  • Construct: strictEquals, struct
  • Introspect at type level: Source, Target, Coverage
  • Lift records: PredicatesToSources, PredicatesToTargets, PredicatesToCoverages, SourcesToPredicates
  • Primitive split: isPrimitive, isNonPrimitive
  • Function shape: isFunction
  • Function arity: isNoArgFunction, isOneArgFunction, isTwoArgFunction
  • Tuple shapes: isSingleton, isReadonlySingleton, isPair, isReadonlyPair, isOverOne, isReadonlyOverOne, isOverTwo, isReadonlyOverTwo

Quickstart

Example (Strict equality and struct refinement)

import { pipe, Array } from "effect"
import * as MPredicate from "@parischap/effect-lib/MPredicate"

// strictEquals
console.log(pipe([1, 2, 3, 2], Array.filter(MPredicate.strictEquals(2)))) // [2, 2]

// struct refinement
type Animal = { readonly name: string; readonly age: number | string }
const isAdult = MPredicate.Struct<Animal, { readonly age: (n: unknown) => n is number }>({
  age: (n): n is number => typeof n === "number" && n >= 18
})

See

  • strictEquals — predicate that tests === against a fixed value
  • struct — enhanced Predicate.struct

Exports Grouped by Category


Constructors

Struct

Enhanced version of Predicate.Struct that supports IDE field completion, allows passing only a subset of the struct fields, and correctly infers a Refinement (instead of a plain Predicate) even when only some fields use refinements.

  • Use to validate part of a struct without writing predicates for every field.
  • Returns a Refinement if at least one field’s predicate is a refinement, otherwise a plain Predicate.
  • Fields not provided are not checked.

Example (Refining a struct on a single field)

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

type Person = { readonly name: string; readonly age: number | string }

const hasNumericAge = MPredicate.Struct<Person, { readonly age: (n: unknown) => n is number }>({
  age: (n): n is number => typeof n === "number"
})

const p: Person = { name: "Alice", age: 30 }
if (hasNumericAge(p)) {
  // `p.age` has been narrowed to `number`
  console.log(p.age + 1) // 31
}

Signature

declare const Struct: <O extends MTypes.NonPrimitive, F extends Partial<SourcesToPredicates<MTypes.Data<O>>>>(
  fields: F
) => [Extract<F[keyof F], MTypes.AnyRefinement>] extends [never]
  ? Predicate.Predicate<O>
  : Predicate.Refinement<
      O,
      {
        readonly [key in keyof O]: key extends keyof F
          ? F[key] extends MTypes.AnyPredicate
            ? Target<F[key]> & O[key]
            : never
          : O[key]
      }
    >

Source

strictEquals

Builds a predicate that tests strict equality (===) against that.

  • Use to filter, partition, or match values that must be referentially equal to a fixed value.
  • Comparison is ===, not Equal.equals; suitable for primitives or when reference identity is intended.
  • The returned predicate accepts any supertype B of that.

Example (Filtering with strictEquals)

import { pipe, Array } from "effect"
import * as MPredicate from "@parischap/effect-lib/MPredicate"

console.log(pipe([1, 2, 3, 2, 1], Array.filter(MPredicate.strictEquals(2)))) // [2, 2]

Signature

declare const strictEquals: <B, A extends B = B>(that: A) => Predicate.Predicate<B>

Source

Instances

isFunction

Refines an unknown value to a function of any arity.

  • Acts as a type guard checking typeof input === 'function'.
  • Use when narrowing unknown data before applying an arity guard such as isOneArgFunction.

Example (Guarding a function)

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

console.log(MPredicate.isFunction(() => 1)) // true
console.log(MPredicate.isFunction(1)) // false

Signature

declare const isFunction: (input: unknown) => input is MTypes.AnyFunction

Source

isNoArgFunction

Refines a function with an unknown number of arguments to one that takes no argument.

  • Acts as a type guard checking f.length === 0.
  • Useful when working with overloaded callbacks where arity matters.

Example (Detecting a nullary callback)

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

console.log(MPredicate.isNoArgFunction(() => 1)) // true
console.log(MPredicate.isNoArgFunction((n: number) => n + 1)) // false

See

  • isOneArgFunction — guard for unary callbacks

Signature

declare const isNoArgFunction: <R>(f: (...args: ReadonlyArray<any>) => R) => f is () => R

Source

isNonPrimitive

Refines an unknown value to a JavaScript non-primitive (record, class instance, array, or function).

  • Acts as a type guard narrowing the input to MTypes.NonPrimitive.
  • Excludes null; includes functions (unlike Predicate.isObject, which excludes them).
  • Use when distinguishing primitives from anything else in unknown data.

Example (Splitting primitives from non-primitives)

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

console.log(MPredicate.isNonPrimitive({ a: 1 })) // true
console.log(MPredicate.isNonPrimitive(() => 1)) // true
console.log(MPredicate.isNonPrimitive(null)) // false
console.log(MPredicate.isNonPrimitive(42)) // false

See

  • isPrimitive — the complementary guard

Signature

declare const isNonPrimitive: <A>(input: A) => input is Exclude<A, MTypes.Primitive> & MTypes.NonPrimitive

Source

isOneArgFunction

Refines a function with an unknown number of arguments to one that takes exactly one argument.

  • Acts as a type guard checking f.length === 1.
  • Useful when working with overloaded callbacks where arity matters.

Example (Detecting a unary callback)

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

console.log(MPredicate.isOneArgFunction((n: number) => n + 1)) // true
console.log(MPredicate.isOneArgFunction((a: number, b: number) => a + b)) // false

See

  • isNoArgFunction — guard for nullary callbacks
  • isTwoArgFunction — guard for binary callbacks

Signature

declare const isOneArgFunction: <A, R>(f: (a: A, ...args: ReadonlyArray<any>) => R) => f is (a: A) => R

Source

isOverOne

Refines an Array<A> to an OverOne<A> (a non-empty array).

  • Acts as a type guard checking u.length > 0.

Example (Guarding a non-empty array)

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

console.log(MPredicate.isOverOne([5])) // true
console.log(MPredicate.isOverOne([])) // false

See

  • isReadonlyOverOne — readonly variant

Signature

declare const isOverOne: <A>(u: Array<A>) => u is MTypes.OverOne<A>

Source

isOverTwo

Refines an Array<A> to an OverTwo<A> (an array with at least two elements).

  • Acts as a type guard checking u.length >= 2.

Example (Guarding an array with two or more elements)

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

console.log(MPredicate.isOverTwo([5, 6])) // true
console.log(MPredicate.isOverTwo([5])) // false

See

  • isReadonlyOverTwo — readonly variant

Signature

declare const isOverTwo: <A>(u: Array<A>) => u is MTypes.OverTwo<A>

Source

isPair

Refines an Array<A> to a Pair<A, A> (a tuple with exactly two elements).

  • Acts as a type guard checking u.length === 2.

Example (Guarding a pair)

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

console.log(MPredicate.isPair([5, 6])) // true
console.log(MPredicate.isPair([5])) // false

See

  • isReadonlyPair — readonly variant

Signature

declare const isPair: <A>(u: Array<A>) => u is MTypes.Pair<A, A>

Source

isPrimitive

Refines an unknown value to a JavaScript primitive (string, number, bigint, boolean, symbol, null, or undefined).

  • Acts as a type guard narrowing the input to MTypes.Primitive.
  • Defined as the negation of isNonPrimitive.

Example (Guarding a primitive)

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

console.log(MPredicate.isPrimitive(42)) // true
console.log(MPredicate.isPrimitive("hi")) // true
console.log(MPredicate.isPrimitive(null)) // true
console.log(MPredicate.isPrimitive([1, 2])) // false

See

  • isNonPrimitive — the complementary guard

Signature

declare const isPrimitive: <A>(input: A) => input is Exclude<A, MTypes.NonPrimitive> & MTypes.Primitive

Source

isReadonlyOverOne

Refines a ReadonlyArray<A> to a ReadonlyOverOne<A> (a non-empty readonly array).

  • Acts as a type guard checking u.length > 0.

See

  • isOverOne — mutable variant

Signature

declare const isReadonlyOverOne: <A>(u: ReadonlyArray<A>) => u is MTypes.ReadonlyOverOne<A>

Source

isReadonlyOverTwo

Refines a ReadonlyArray<A> to a ReadonlyOverTwo<A> (a readonly array with at least two elements).

  • Acts as a type guard checking u.length >= 2.

See

  • isOverTwo — mutable variant

Signature

declare const isReadonlyOverTwo: <A>(u: ReadonlyArray<A>) => u is MTypes.ReadonlyOverTwo<A>

Source

isReadonlyPair

Refines a ReadonlyArray<A> to a ReadonlyPair<A, A> (a tuple with exactly two elements).

  • Acts as a type guard checking u.length === 2.

See

  • isPair — mutable variant

Signature

declare const isReadonlyPair: <A>(u: ReadonlyArray<A>) => u is MTypes.ReadonlyPair<A, A>

Source

isReadonlySingleton

Refines a ReadonlyArray<A> to a ReadonlySingleton<A> (a tuple with exactly one element).

  • Acts as a type guard checking u.length === 1.

See

  • isSingleton — mutable variant

Signature

declare const isReadonlySingleton: <A>(u: ReadonlyArray<A>) => u is MTypes.ReadonlySingleton<A>

Source

isSingleton

Refines an Array<A> to a Singleton<A> (a tuple with exactly one element).

  • Acts as a type guard checking u.length === 1.

Example (Guarding a singleton)

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

console.log(MPredicate.isSingleton([5])) // true
console.log(MPredicate.isSingleton([5, 6])) // false

See

  • isReadonlySingleton — readonly variant

Signature

declare const isSingleton: <A>(u: Array<A>) => u is MTypes.Singleton<A>

Source

isTwoArgFunction

Refines a function with an unknown number of arguments to one that takes exactly two arguments.

  • Acts as a type guard checking f.length === 2.

Example (Detecting a binary callback)

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

console.log(MPredicate.isTwoArgFunction((a: number, b: number) => a + b)) // true
console.log(MPredicate.isTwoArgFunction((n: number) => n + 1)) // false

See

  • isOneArgFunction — guard for unary callbacks

Signature

declare const isTwoArgFunction: <A, B, R>(f: (a: A, b: B, ...args: ReadonlyArray<any>) => R) => f is (a: A, b: B) => R

Source

Models

PredicateEffect (interface)

An effectful predicate: a function from Z to Effect<boolean, E, R>.

  • Use when the predicate result depends on an effectful computation (I/O, async, etc.).
  • Mirrors Predicate.Predicate but lifted into Effect.

Signature

export interface PredicateEffect<in Z, out E, out R> {
  (x: Z): Effect.Effect<boolean, E, R>
}

Source

Utility types

Coverage (type alias)

Type utility extracting the type a refinement narrows to, returning never for plain predicates.

  • Returns B for Predicate.Refinement<A, B>.
  • Returns never for Predicate.Predicate<A> (since plain predicates do not narrow).
  • Useful for computing what a refinement removes from a remaining input space.

Signature

type Coverage<R extends MTypes.AnyPredicate> = readonly [R] extends readonly [Predicate.Refinement<infer _, infer A>]
  ? A
  : never

Source

PredicatesToCoverages (type alias)

Type utility mapping an array/record of predicates to an array/record of their coverages.

Signature

type PredicatesToCoverages<T extends PredicateArray> = {
  readonly [key in keyof T]: Coverage<T[key]>
}

Source

PredicatesToSources (type alias)

Type utility mapping an array/record of predicates to an array/record of their sources.

Signature

type PredicatesToSources<T extends PredicateArray> = {
  readonly [key in keyof T]: Source<T[key]>
}

Source

PredicatesToTargets (type alias)

Type utility mapping an array/record of predicates to an array/record of their targets.

Signature

type PredicatesToTargets<T extends PredicateArray> = {
  readonly [key in keyof T]: Target<T[key]>
}

Source

Source (type alias)

Type utility extracting the source type of a predicate or refinement.

  • For Predicate.Predicate<A> and Predicate.Refinement<A, B> it returns A.
  • Useful when generic code must reason about the input of an unknown predicate.

Example (Extracting the source)

import type * as MPredicate from "@parischap/effect-lib/MPredicate"
import type * as Predicate from "effect/Predicate"

type _Source = MPredicate.Source<Predicate.Refinement<unknown, string>> // unknown

Signature

type Source<R extends MTypes.AnyPredicate> = readonly [R] extends readonly [Predicate.Predicate<infer A>] ? A : never

Source

SourcesToPredicates (type alias)

Type utility mapping an array/record of values to an array/record of predicates over those values.

Signature

type SourcesToPredicates<T extends MTypes.NonPrimitive> = {
  readonly [key in keyof T]: Predicate.Predicate<T[key]>
}

Source

Target (type alias)

Type utility extracting the narrowed type of a predicate or refinement.

  • For Predicate.Refinement<A, B> it returns B.
  • For Predicate.Predicate<A> it returns A (no narrowing).

Example (Extracting the target)

import type * as MPredicate from "@parischap/effect-lib/MPredicate"
import type * as Predicate from "effect/Predicate"

type _Target = MPredicate.Target<Predicate.Refinement<unknown, string>> // string

Signature

type Target<R extends MTypes.AnyPredicate> = readonly [R] extends readonly [Predicate.Refinement<infer _, infer A>]
  ? A
  : Source<R>

Source