From 6111f95c79912ccd8924b676a45152612c077fa6 Mon Sep 17 00:00:00 2001 From: Phil Pluckthun Date: Fri, 10 Mar 2023 19:18:50 +0000 Subject: [PATCH] fix: Add missing filter overload to allow for type narrowing (#149) --- .changeset/khaki-lemons-argue.md | 5 +++++ src/__tests__/operators.test.ts | 6 ++++-- src/operators.ts | 10 +++++++--- 3 files changed, 16 insertions(+), 5 deletions(-) create mode 100644 .changeset/khaki-lemons-argue.md diff --git a/.changeset/khaki-lemons-argue.md b/.changeset/khaki-lemons-argue.md new file mode 100644 index 0000000..a1cfeda --- /dev/null +++ b/.changeset/khaki-lemons-argue.md @@ -0,0 +1,5 @@ +--- +'wonka': patch +--- + +Add missing overload definition for `filter`, which allows types to be narrowed, e.g. by specifying a type predicate return type. diff --git a/src/__tests__/operators.test.ts b/src/__tests__/operators.test.ts index db19097..e22f5d6 100644 --- a/src/__tests__/operators.test.ts +++ b/src/__tests__/operators.test.ts @@ -231,10 +231,12 @@ describe('filter', () => { passesAsyncSequence(noop); it('prevents emissions for which a predicate fails', () => { - const { source, next } = sources.makeSubject(); + const { source, next } = sources.makeSubject(); const fn = vi.fn(); - sinks.forEach(fn)(operators.filter(x => !!x)(source)); + sinks.forEach((x: true) => { + fn(x); + })(operators.filter((x): x is true => !!x)(source)); next(false); expect(fn).not.toHaveBeenCalled(); diff --git a/src/operators.ts b/src/operators.ts index 3a09936..06f57d2 100644 --- a/src/operators.ts +++ b/src/operators.ts @@ -1,4 +1,4 @@ -import { Source, Sink, Operator, SignalKind, TalkbackKind, TalkbackFn } from './types'; +import { Push, Source, Sink, Operator, SignalKind, TalkbackKind, TalkbackFn } from './types'; import { push, start, talkbackPlaceholder } from './helpers'; import { fromArray } from './sources'; @@ -268,7 +268,9 @@ export function concat(sources: Source[]): Source { * ); * ``` */ -export function filter(predicate: (value: T) => boolean): Operator { +function filter(predicate: (value: In) => value is Out): Operator; +function filter(predicate: (value: T) => boolean): Operator; +function filter(predicate: (value: In) => boolean): Operator { return source => sink => { let talkback = talkbackPlaceholder; source(signal => { @@ -280,12 +282,14 @@ export function filter(predicate: (value: T) => boolean): Operator { } else if (!predicate(signal[0])) { talkback(TalkbackKind.Pull); } else { - sink(signal); + sink(signal as Push); } }); }; } +export { filter }; + /** Maps emitted values using the passed mapping function. * * @param map - A function returning transforming the {@link Source | Source's} values.