top | item 14579692

(no title)

jamesisaac | 8 years ago

> Option 1: Use a string or null/false data [...] If you're using a type checker like #flow, it will yell at you and for a good reason: data type changes are hard to reason about and very error prone in practice.

This isn't true. Flow is great at enforcing that all potential types/values are handled in an if statement. If the following type was used, the code missing the failure case would have been picked up by Flow:

    type Pics = 'fetching' | 'failed' | Array<Pic>
> Option 2: use an object with two props [...] someone accidentally changes the status without changing the data. Or the other way around. This will result in nasty and hard to debug issues where the state and data don't match visually.

Again, this can be avoided by using the correct union in Flow, which will pick up right away if the two properties have become inconsistent:

    type PicsState =
      | { status: 'fetching', list: null }
      | { status: 'failed', list: null }
      | { status: 'fetched', list: Array<Pic> }

discuss

order

michaelmartin|8 years ago

Hadn't seen the union approach in #2 before, I like that a lot. The 2 named properties are intuitive to other developers reading it, but now we also get compile-time safety that the combinations they use are valid. Thanks!

For anyone else that this was new to, Flow has documented these as "disjoint unions": https://flow.org/en/docs/types/unions/#toc-disjoint-unions