Predicate combinators don't infer types when composed with other predicates
What is the problem this feature would solve?
When I use Predicate combinator like Predicate.some or Predicate.all with other predicated I loose type safety (the new predicate is not correctly inferred). For example:
const _ = Predicate.some([
// ^? Predicate.Predicate<unknown>
Predicate.isTagged("SomeTag"),
Predicate.isTagged("SomeOtherTag")
])
The implementation of .some seems to force the collection it receives to be an iterable over only one predicate type, which from some reason turns it into unknown, even when you only have one item in the collection. This makes the resulting predicate somewhat useless to me since I cannot use for narrowing any more.
What is the feature you are proposing to solve the problem?
Changing the call signature from <A>(collection: Iterable<Predicate<A>>) => Predicate<A> to something like <A extends Predicate<any>>(collection: Iterable<A>) => Predicate<A> where we allow the collection to be an iterable over a union of predicates seems to do the trick. The same thing is probably true for the .all combinator, and maybe others.
I can file a PR if this seems like the right approach, but it might have (type) implications I have not considered.
What alternatives have you considered?
I currently have a custom PredicateSome implementation. I could continue to use that.
I think this can be fixed if we make the signatures something like this.
Instead Array.Infer<> we could introduce namespace Iterable.Iterable
BTW ReadonlyArray in return types can be changed to just Array
Now I’m not sure about using just Array, because I’ve seen some mentions of variance related to readonly array.
my 2 cents: https://github.com/Effect-TS/effect/pull/5657