import type * as T from './types.js' import * as t from './schema.js' type Predicate = T.Predicate | t.Schema /** * ## {@link filter `t.filter`} */ export function filter, T extends t.LowerBound>(schema: S, filter: T): T export function filter, T extends S['_type']>(schema: S, filter: (s: S['_type']) => s is T): t.of export function filter(schema: S, filter: (s: S['_type']) => boolean): S export function filter(guard: T.Guard, narrower: (x: T) => x is U): T.Guard export function filter(guard: T.Guard, predicate: (x: T) => boolean): T.Guard export function filter(guard: T.Guard): (predicate: (x: T) => boolean) => T.Guard export function filter(...args: [guard: T.Guard] | [guard: T.Guard, predicate: T.Predicate]) { if (args.length === 1) return (predicate: T.Predicate) => filter(args[0], predicate) else return (x: T) => args[0](x) && args[1](x) } // TODO: investigate this more plz // // export function compose(f: (a: A) => a is B, g: (b: B) => b is C): (b: B) => b is C // // compose(t.number, (x) => x === 9000) // ^? (u: number) => u is 9000 <-- INTERESTING... // this _actually_ seems type-safe, since t.number goes from unknown -> number? // might need to tweak the runtime impl a bit... // /** // * ## {@link compose `t.compose`} // */ // export function compose>(f: A, g: B): B // export function compose(f: A, g: (t: A['_type']) => boolean): A // export function compose(f: (a: A) => a is B, g: (b: B) => b is C): t.inline // export function compose(f: (a: A) => a is B, g: (b: B) => boolean): t.inline // // export function compose(f: (a: A) => boolean, g: (a: A) => a is B): t.inline // export function compose(f: (a: A) => B | boolean, g: (a: A) => B | boolean): (a: A) => B | boolean { // return (a: A) => { // const b = f(a) // return b === false ? false : b === true ? g(a) : g(b) // } // }