geninq
Version:
A JavaScript version of the Linq library for Generators
136 lines (124 loc) • 5.36 kB
text/typescript
import { IsString } from "@paulpopat/safe-type";
import "./array";
import { Build, Promised } from "./utils";
declare global {
interface Generator<T = unknown, TReturn = any, TNext = unknown> {
/**
* Returns the last element of a sequence.
* @returns The value at the last position in the source sequence.
*/
last(): T;
/**
* Returns the last element of a sequence that satisfies a specified condition.
* @param predicate A function to test each element for a condition.
* @returns The last element in the sequence that passes the test in the specified predicate function.
*/
last(predicate: (item: T) => boolean): T;
/**
* Returns the last element of a sequence that matches the specified type.
* @param predicate A type checker function to test each element for a condition.
* @returns The last element in the sequence that matches the specified type.
*/
last<TResult extends T>(predicate: (item: T) => item is TResult): TResult;
/**
* Returns the last element of a sequence, or undefined if the sequence contains no elements.
* @param allow_undefined Specify that undefined should be returned if no elements.
* @returns undefined if the source sequence is empty; otherwise, the last element in the sequence.
*/
last(allow_undefined: "or-default"): T | undefined;
/**
* Returns the last element of a sequence that satisfies a
* condition or undefined if no such element is found.
* @param predicate A function to test each element for a condition.
* @param allow_undefined Specify that undefined should be returned if no elements.
* @returns undefined if the sequence is empty or if no elements pass the test in the predicate function; otherwise, the last element that passes the test in the predicate function.
*/
last(
predicate: (item: T) => boolean,
allow_undefined: "or-default"
): T | undefined;
/**
* Returns the last element of a sequence that matches the type provided or undefined if no such element is found.
* @param predicate A type checker function to test each element for a condition.
* @param allow_undefined Specify that undefined should be returned if no elements.
* @returns undefined if the sequence is empty or if no elements pass the test in the predicate function; otherwise, the last element that matches the type provided.
*/
last<TResult extends T>(
predicate: (item: T) => item is TResult,
allow_undefined: "or-default"
): TResult | undefined;
}
interface AsyncGenerator<T = unknown, TReturn = any, TNext = unknown> {
/**
* Returns the last element of a sequence.
* @returns The value at the last position in the source sequence.
*/
last(): Promise<T>;
/**
* Returns the last element of a sequence that satisfies a specified condition.
* @param predicate A function to test each element for a condition.
* @returns The last element in the sequence that passes the test in the specified predicate function.
*/
last(predicate: (item: T) => Promised<boolean>): Promise<T>;
/**
* Returns the last element of a sequence, or undefined if the sequence contains no elements.
* @param allow_undefined Specify that undefined should be returned if no elements.
* @returns undefined if the source sequence is empty; otherwise, the last element in the sequence.
*/
last(allow_undefined: "or-default"): Promise<T | undefined>;
/**
* Returns the last element of a sequence that satisfies a
* condition or undefined if no such element is found.
* @param predicate A function to test each element for a condition.
* @param allow_undefined Specify that undefined should be returned if no elements.
* @returns undefined if the sequence is empty or if no elements pass the test in the predicate function; otherwise, the last element that passes the test in the predicate function.
*/
last(
predicate: (item: T) => Promised<boolean>,
allow_undefined: "or-default"
): Promise<T | undefined>;
}
}
Build(
"last",
function (predicate, allow_undefined) {
if (IsString(predicate)) {
allow_undefined = predicate as "or-default";
predicate = (i): i is unknown => true;
} else if (!predicate) {
predicate = (i): i is unknown => true;
}
let last_match: unknown;
let part = this.next();
while (!part.done) {
if (predicate(part.value)) {
last_match = part.value;
}
part = this.next();
}
if (last_match === undefined && !allow_undefined) {
throw new Error("No matches for sequence");
}
return last_match;
},
async function (predicate, allow_undefined) {
if (IsString(predicate)) {
allow_undefined = predicate as "or-default";
predicate = (i): i is unknown => true;
} else if (!predicate) {
predicate = (i): i is unknown => true;
}
let last_match: unknown;
let part = await this.next();
while (!part.done) {
if (predicate(part.value)) {
last_match = part.value;
}
part = await this.next();
}
if (last_match === undefined && !allow_undefined) {
throw new Error("No matches for sequence");
}
return last_match;
}
);