'Flow disjoint union based on if property exists

I wonder if there is any way that I can refine a disjoint union based on if a property exists, something like this:

type Success = {| success: string |};
type Failed = {| error: string |};

type Response = Success | Failed;

function handleResponse(response: Response) {
  if (response.hasOwnProperty('success')) {
    // It is a Success
    var value: string = response.success;
  } else {
    // It is an Error
    var message: string = response.error;
  }
}

This code gives me the following errors:

11:     var value: string = response.success;
                                     ^ Cannot get `response.success` because property `success` is missing in `Failed` [1].
References:
8: function handleResponse(response: Response) {
                                     ^ [1]
14:     var message: string = response.error;
                                       ^ Cannot get `response.error` because property `error` is missing in `Success` [1].
References:
8: function handleResponse(response: Response) {
                                     ^ [1]

I want to be sure that if the first if statement is true, the response is a Sucess, otherwise it is an Error without changing the Success or Failed types.

Try Link



Solution 1:[1]

It's not possible in the way you would like. Here's an example of a discussion about what you want on GitHub.

What you provided above is not actually a disjoint union, it's simply a union. Using a shared prop that differentiates the two would be a disjoint union, and there it is possible to do type refinement. Here's a Try Link.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Andrew Smith