Skip to content

Commit

Permalink
Merge pull request #21 from 4513ECHO/filter-overload
Browse files Browse the repository at this point in the history
fix(filter): Support narrowing by type predicate
  • Loading branch information
lambdalisue authored Aug 20, 2024
2 parents 85fd83b + 78d4eaf commit 2cf67f5
Show file tree
Hide file tree
Showing 8 changed files with 66 additions and 0 deletions.
8 changes: 8 additions & 0 deletions async/filter.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
export function filter<T, U extends T>(
iterable: Iterable<T> | AsyncIterable<T>,
fn: (value: T, index: number) => value is U,
): AsyncIterable<U>;
export function filter<T>(
iterable: Iterable<T> | AsyncIterable<T>,
fn: (value: T, index: number) => boolean | Promise<boolean>,
): AsyncIterable<T>;
/**
* Filters an iterable based on a function.
*
Expand Down
8 changes: 8 additions & 0 deletions async/filter_test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,3 +69,11 @@ await test("filter with iterable with promise", async () => {
assertEquals(indices, [0, 1, 2, 3, 4]);
assertType<IsExact<typeof result, AsyncIterable<number>>>(true);
});

await test("filter with type predicate", async () => {
const predicate = (v: number | string): v is number => typeof v === "number";
const result = filter([1, "a", 2, "b", 3], predicate);
const expected = [1, 2, 3];
assertEquals(await Array.fromAsync(result), expected);
assertType<IsExact<typeof result, AsyncIterable<number>>>(true);
});
8 changes: 8 additions & 0 deletions filter.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
export function filter<T, U extends T>(
iterable: Iterable<T>,
fn: (value: T, index: number) => value is U,
): Iterable<U>;
export function filter<T>(
iterable: Iterable<T>,
fn: (value: T, index: number) => boolean,
): Iterable<T>;
/**
* Filters an iterable based on a function.
*
Expand Down
8 changes: 8 additions & 0 deletions filter_test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,11 @@ test("filter", () => {
assertEquals(indices, [0, 1, 2, 3, 4]);
assertType<IsExact<typeof result, Iterable<number>>>(true);
});

test("filter with type predicate", () => {
const predicate = (v: number | string): v is number => typeof v === "number";
const result = filter([1, "a", 2, "b", 3], predicate);
const expected = [1, 2, 3];
assertEquals(Array.from(result), expected);
assertType<IsExact<typeof result, Iterable<number>>>(true);
});
6 changes: 6 additions & 0 deletions pipe/async/filter.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
import { filter as base } from "../../async/filter.ts";

export function filter<T, U extends T>(
fn: (value: T, index: number) => value is U,
): (iterable: Iterable<T> | AsyncIterable<T>) => AsyncIterable<U>;
export function filter<T>(
fn: (value: T, index: number) => boolean | Promise<boolean>,
): (iterable: Iterable<T> | AsyncIterable<T>) => AsyncIterable<T>;
/**
* Returns an operator that filters an iterable based on a function.
*
Expand Down
11 changes: 11 additions & 0 deletions pipe/async/filter_test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,14 @@ test("filter usage", async () => {
assertEquals(await Array.fromAsync(result), expected);
assertType<IsExact<typeof result, AsyncIterable<number>>>(true);
});

test("filter usage with type predicate", async () => {
const predicate = (v: number | string): v is number => typeof v === "number";
const result = pipe(
[1, "a", 2, "b", 3],
filter(predicate),
);
const expected = [1, 2, 3];
assertEquals(await Array.fromAsync(result), expected);
assertType<IsExact<typeof result, AsyncIterable<number>>>(true);
});
6 changes: 6 additions & 0 deletions pipe/filter.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
import { filter as base } from "../filter.ts";

export function filter<T, U extends T>(
fn: (value: T, index: number) => value is U,
): (iterable: Iterable<T>) => Iterable<U>;
export function filter<T>(
fn: (value: T, index: number) => boolean,
): (iterable: Iterable<T>) => Iterable<T>;
/**
* Returns an operator that filters an iterable based on a function.
*
Expand Down
11 changes: 11 additions & 0 deletions pipe/filter_test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,14 @@ test("filter usage", () => {
assertEquals(Array.from(result), expected);
assertType<IsExact<typeof result, Iterable<number>>>(true);
});

test("filter usage with type predicate", () => {
const predicate = (v: number | string): v is number => typeof v === "number";
const result = pipe(
[1, "a", 2, "b", 3],
filter(predicate),
);
const expected = [1, 2, 3];
assertEquals(Array.from(result), expected);
assertType<IsExact<typeof result, Iterable<number>>>(true);
});

0 comments on commit 2cf67f5

Please sign in to comment.