UNPKG

geninq

Version:

A JavaScript version of the Linq library for Generators

95 lines (83 loc) 2.54 kB
import { IsString } from "@paulpopat/safe-type"; import { Build, Promised } from "./utils"; declare global { interface Generator<T = unknown, TReturn = any, TNext = unknown> { single(): T; single(allow_empty: "or-default"): T | undefined; single(predicate: (item: T) => boolean): T; single( predicate: (item: T) => boolean, allow_empty: "or-default" ): T | undefined; single<TRes extends T>(predicate: (item: T) => item is TRes): TRes; single<TRes extends T>( predicate: (item: T) => item is TRes, allow_empty: "or-default" ): TRes | undefined; } interface AsyncGenerator<T = unknown, TReturn = any, TNext = unknown> { single(): Promise<T>; single(allow_empty: true): Promise<T | undefined>; single(predicate: (item: T) => Promised<boolean>): Promise<T>; single( predicate: (item: T) => Promised<boolean>, allow_empty: true ): Promise<T | undefined>; single<TRes extends T>(predicate: (item: T) => item is TRes): Promise<TRes>; single<TRes extends T>( predicate: (item: T) => item is TRes, allow_empty: "or-default" ): Promise<TRes | undefined>; } } Build( "single", function (predicate, allow_empty) { if (IsString(predicate)) { allow_empty = predicate as "or-default"; predicate = (i): i is unknown => true; } else if (!predicate) { predicate = (i): i is unknown => true; } const matches = []; for (const item of this) { if (predicate(item)) { matches.push(item); if (matches.length > 1) { throw new Error("Too many matches in sequence"); } } } if (matches.length === 1) { return matches[0]; } if (allow_empty) { return undefined; } throw new Error("No matching elements in sequence."); }, async function (predicate, allow_empty) { if (IsString(predicate)) { allow_empty = predicate as "or-default"; predicate = (i): i is unknown => true; } else if (!predicate) { predicate = (i): i is unknown => true; } const matches = []; for await (const item of this) { if (await Promise.resolve(predicate(item))) { matches.push(item); if (matches.length > 1) { throw new Error("Too many matches in sequence"); } } } if (matches.length === 1) { return matches[0]; } if (allow_empty) { return undefined; } throw new Error("No matching elements in sequence."); } );