Flow: Destructuring union types with string literals does not work in function parameters

Created on 2 Jun 2018  路  6Comments  路  Source: facebook/flow

Issue

Flow throws cryptic error messages when destructuring a union type that contains a string literal inside function parameters. However, if you destructure with the same fields inside the function body, no errors are thrown.

Reproduced using Flow 0.73.0: Try Flow

type MyType = { __typename: 'A' }  | { __typename: 'B' };

// Destructuring in function body - works
const works = (t: MyType) => {
    const { __typename } = t;
    if (__typename === 'A') {
        console.log('A');
    }
}

// Destructuring in function params - does NOT work
const doesntWork = ({ __typename }: MyType) => {
    if (__typename === 'A') {
        console.log('A');
    }
}

Errors

12: const doesntWork = ({ __typename }: MyType) => {
                          ^ string literal `B` [1] is incompatible with string literal `A` [2].
References:
1: type MyType = { __typename: 'A' }  | { __typename: 'B' };
                                                      ^ [1]
1: type MyType = { __typename: 'A' }  | { __typename: 'B' };
                               ^ [2]

Expected

Behavior inside the function and inside the function parameters is the same.

Actual

Behavior inside the function parameters throws errors, while doing the exact same destructuring is fine inside the function body.

Related Tickets

https://github.com/facebook/flow/issues/5461
https://github.com/facebook/flow/issues/5745

unionintersections bug destructuring feature request

All 6 comments

Yeah, this is one worth looking into. Thanks for the report and finding the related tickets 馃憤

It seems to work fine when you provide a default value to the destructured property, but that defeats the purpose... Try Flow

Interesting, it "works" (no errors) with a default value that's not a valid string literal based on the union type:
Try Flow

Hmmm interesting. Welp, looks like a general problem with destructuring in params then.

any update here ?
:)

The code looks also not work,

type Props = {
  value: boolean | string
}

function test({ value = true }: Props) {}

show errors:

5: function test({ value = true }: Props) {}
                   ^ boolean [1] is incompatible with string [2].
References:
2:   value: boolean | string
            ^ [1]
2:   value: boolean | string                      
                      ^ [2]


5: function test({ value = true }: Props) {}
                           ^ boolean [1] is incompatible with string [2].
References:
5: function test({ value = true }: Props) {}
                           ^ [1]
2:   value: boolean | string                      
                      ^ [2]
Was this page helpful?
0 / 5 - 0 ratings

Related issues

glenjamin picture glenjamin  路  3Comments

ghost picture ghost  路  3Comments

davidpelaez picture davidpelaez  路  3Comments

cubika picture cubika  路  3Comments

jamiebuilds picture jamiebuilds  路  3Comments