rivo
Version:
🤖 The ultimate library you need for composable type-level programming in TypeScript, powered by HKT.
49 lines (44 loc) • 1.91 kB
TypeScript
import type { List } from ".";
// @ts-ignore - Only used in doc comments
import type { Reject } from "./Reject";
// @ts-ignore - Only used in doc comments
import type RejectFn from "./Reject";
import type { Args, Call1W, Fn1, GenericFn, GenericResolver, Param0 } from "../HKT";
type _FilterMutableList<Pred extends Fn1<never, boolean>, TS extends List> =
number extends TS["length"] ? TS
: TS extends [infer Head, ...infer Tail] ?
Call1W<Pred, Head> extends true ?
[Head, ..._FilterMutableList<Pred, Tail>]
: _FilterMutableList<Pred, Tail>
: [];
type _FilterImmutableList<Pred extends Fn1<never, boolean>, TS extends List> =
number extends TS["length"] ? TS
: TS extends readonly [infer Head, ...infer Tail] ?
Call1W<Pred, Head> extends true ?
readonly [Head, ..._FilterImmutableList<Pred, Tail>]
: _FilterImmutableList<Pred, Tail>
: readonly [];
/**
* Filter a {@link List} (i.e., fixed-length tuple) based on a predicate.
*
* Sig: `<T>(pred: (x: T => boolean), xs: List<T>) => List<T>`
*
* @see {@link Reject} for the opposite.
*/
export type Filter<Pred extends Fn1<never, boolean>, TS extends List> =
TS extends unknown[] ? _FilterMutableList<Pred, TS> : _FilterImmutableList<Pred, TS>;
interface Resolver extends GenericResolver<[Fn1<never, boolean>, List], List> {
on1_: ([pred]: Args<this>) => [[List<Param0<typeof pred>>], List<Param0<typeof pred>>];
on_1: ([, xs]: Args<this>) => [[Fn1<(typeof xs)[number], boolean>], List<(typeof xs)[number]>];
on11: ([pred, xs]: Args<this>) => [[], List<(typeof xs)[number]>];
}
/**
* [Fn] Filter a {@link List} (i.e., fixed-length tuple) based on a predicate.
*
* Sig: `<T>(pred: (x: T => boolean), xs: List<T>) => List<T>`
*
* @see {@link RejectFn} for the opposite.
*/
export default interface FilterFn extends GenericFn<Resolver> {
def: ([pred, xs]: Args<this>) => Filter<typeof pred, typeof xs>;
}