baconjs / bacon.js

Functional reactive programming library for TypeScript and JavaScript
https://baconjs.github.io
MIT License
6.47k stars 330 forks source link

Observable.filter with type guard predicate #739

Open joux3 opened 5 years ago

joux3 commented 5 years ago

Array.filter can change the type of the array when passed a user-defined type guard. See for example this:

// this gets inferred as (number | string)[]
const numberOrStringArray = [1, 2, 'jee']
// this is inferred as number[] thanks to the type guard
const numberArray = numberOrStringArray
  .filter((x): x is number => typeof x === 'number')

Could Observable.filter support a similar type guard? The type definition for Array.filter in the example is:

filter<S extends T>(callbackfn: (value: T, index: number, array: T[]) => value is S, thisArg?: any): S[];
raimohanska commented 5 years ago

This is a nice idea! Want to have a stab at this yourself?

raimohanska commented 5 years ago

Filter is a bit hard to modify, because it's already quite overloaded:

filter(f: Predicate<V> | boolean | Property<boolean>): this

A new operator on EventStream and Property can be added though:

  narrow<V2 extends V>(f: IsA<V, V2>): EventStream<V2> {
    return <any>filter<V>(this, f)
  }

What should we call it?

raimohanska commented 5 years ago

WIP at 745de93ddeaae39537bf494eb2a9b7adbc3a2d25