Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Flowtype and .filter() #11

Open
benadamstyles opened this issue Apr 18, 2017 · 5 comments
Open

Flowtype and .filter() #11

benadamstyles opened this issue Apr 18, 2017 · 5 comments

Comments

@benadamstyles
Copy link
Contributor

I have been looking at the maybe source code and trying to work out how to improve the typing of the .filter() method but I haven't worked anything out. The problem is below. Is it possible to fix this within maybe or is flow not able to handle this anyway yet?

maybe(getUserType()) // => 'admin' | 'customer'
  .filter(userType => userType !== 'admin')
  .forEach((userType: 'customer') => // => flow complains that userType is 'admin' | 'customer'
    doSomethingOnlyCustomerCanDo(userType)
  )
@alexanderjarvis
Copy link
Owner

Hi @Leeds-eBooks,

The problem is that filter returns the same type A as wrapped in Maybe (in this case the union of 'admin' | 'customer'.

Essentially what you want is to restrict the type, but you probably don't need to. I would suggest allowing the doSomething() function to allow either type and just have this runtime validation with maybe.filter.

Alternatively you may want to look at type aliases, or classes to represent your user objects instead.

Thanks!

@alexanderjarvis
Copy link
Owner

Also conceptually, filter shouldn't change the value of A. What you're after is actually similar to Scala's collect() which is like filter and map combined.

@maartenschumacher
Copy link
Contributor

maartenschumacher commented Apr 18, 2017

What about:
.flatMap(userType => userType !== 'admin' ? just(userType) : nothing)
It looks a bit janky but it would solve your type problem.

@benadamstyles
Copy link
Contributor Author

@maartenschumacher That works a treat, thanks so much.

@alexanderjarvis would it make sense to add this method to maybe? I mean something like:

collect(p: (A) => boolean): Maybe<B> {
  if (p(this.value)) {
    return just(this.value)
  } else {
    return nothing
  }
}

That's probably all wrong but just for illustrative purposes.

@maartenschumacher
Copy link
Contributor

How would you define B? What you're trying to do is refine the type, for which Flow does have some internal representations: https://github.com/facebook/flow/blob/dd0603e9d8c9d5fb99a40f0b179a4d6a2b9e66b7/tests/predicates-abstract/refine.js
But the question is if this stuff will ever be exposed in a nice way

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants