Flow: Optional arguments cannot be called with non-optional value

Created on 17 Dec 2019  路  5Comments  路  Source: facebook/flow

Flow version: v0.114.0

type Arg = {
  someProp: string,
  maybeOptional?: string
}

const someFunc = (arg: Arg) => {
  return arg
}


type OtherArg = {
  someProp: string,
  maybeOptional: string
}

const otherFunc = (otherArg: OtherArg) => {
    return someFunc(otherArg)
}

Expected behavior

When an optional field is provided an error should not be raised.
Use case:
Generic component that optionally performs certain functionality - A particular implementation of that generic component that we always expect to have that functionality

Actual behavior

Cannot call someFunc with otherArg bound to arg because string [1] is incompatible with undefined [2] in property maybeOptional.

https://flow.org/try/#0PQKgBAAgZgNg9gdzCYAodAXAngBwKZgCCATgOZgC8YA3qmGAM5wC2eACsXDgFyMbEBLAHakANHTDMAhlgBGeAPI4MAuEKkwA-Lwb9hpVAF90AYzW7GLPADEArkJOUwACilleJUgEpKAPhoSxHgYtsRCYG4Gxpi4BAoYABZ4xJ5OtPRMrBxcOnoi4vTScorKquowuYIiRqbmGGBwicl2Dk7OjUkp7mDxnZ4+FP60AJBBIWGWrC0m7U1d3jWoQA

bug needs triage

Most helpful comment

$ReadOnlyArray :-)

I recommend to always use at least $ReadOnlyArray instead of Array. Manipulations with Array give more problems than with writable objects.

https://flow.org/try/#0PQKgBAAgZgNg9gdzCYAoVAXAngBwKZgCCATgOZgC8YAJAEp4CGAJgPIB2MWJxDWAPHUasO-AN6owYAM5wAtngAKxODgBc0jMQCWbUgBoJYWbwBGeFjgxa4bBjAD86qZp2lUAXwB8ngNzoAxjbO0nJ4AGIArmz+lGAAFAxk6iSkAJSUnmDiksR4GBHEbGCJbu7omLgELBgAFnjEKbHcvHzZIfJKKk4uugaSxlhmFlY2dt3auh6+AUEYYHC19ZHRsXELdQ1JYNUbKekUmeIAkLn5he3hUf5ri5tpHuhAA

All 5 comments

This is because object with optional property can be mutated and the original object will be changed. This is unsound. To solve the problem you need to add guarantee the object cannot be mutated with $ReadOnly utility type.

https://flow.org/try/#0PQKgBAAgZgNg9gdzCYAodAXAngBwKZgCCATgOZgC8YAJAEp4CGAJgPIB2MWAPAN6phgAznAC2eAArE4OAFxCMxAJZtSAGn5gRDLACM8LHBkVw2DGAH45ghctKoAvgD50AYxPWhovADEArmxdKMAAKBjI5ElIASkpHMD4BYjwMX2I2MDC7e3RUbHwwFgwACzxiSKCEzzFJaSsbFXUBLV19Q2NTGDqlFQdXdwwwOGLSvwCg4KGSsvCC4eno2PjUAEgklLSqn38XCbnIqN7UIA

This makes sense - thank you

Hey apologies - my specific use case actually uses an array of these objects and the read only approach is not working. What am I missing?

/* @flow */

type Arg = Array<$ReadOnly<{
  someProp: string,
  maybeOptional?: string
}>>;

const someFunc = (arg: Arg) => {
  return arg
}


type OtherArg = Array<{
  someProp: string,
  maybeOptional: string
}>;

const otherFunc = (otherArg: OtherArg) => {
    return someFunc(otherArg)
}

This raised that the values in OtherArg are writable but read only in Arg

Also tried with

type OtherArg = Array<$ReadOnly<{
  someProp: string,
  maybeOptional: string
}>>;

const otherFunc = (otherArg: OtherArg) => {
    return someFunc(otherArg)
}

Which raised original issue

https://flow.org/try/#0PQKgBAAgZgNg9gdzCYAoVAXAngBwKZgCCATgOZgC8RxxAhlgDwAkASnrQCYDyAdjIwG9UYMAGc4AWzwAFYnBwAuMRmIBLHqQA0wsBPoAjPFxwZVcHrRgB+JaJXrSqAL4A+FwG50AY3N2xkvAAxAFceL0owAApaMiUSUgBKShcwIRFiPAxg4h4wGMcndExcAi4MAAs8YniIkjpBHXEpWXlbew1tET0sQ2NTc0s2tQ1nD29fDDA4CqqQsIjI6crq2LAy5fikihShAEgMrJz-KTmvRZmVxOd0IA

$ReadOnlyArray :-)

I recommend to always use at least $ReadOnlyArray instead of Array. Manipulations with Array give more problems than with writable objects.

https://flow.org/try/#0PQKgBAAgZgNg9gdzCYAoVAXAngBwKZgCCATgOZgC8YAJAEp4CGAJgPIB2MWJxDWAPHUasO-AN6owYAM5wAtngAKxODgBc0jMQCWbUgBoJYWbwBGeFjgxa4bBjAD86qZp2lUAXwB8ngNzoAxjbO0nJ4AGIArmz+lGAAFAxk6iSkAJSUnmDiksR4GBHEbGCJbu7omLgELBgAFnjEKbHcvHzZIfJKKk4uugaSxlhmFlY2dt3auh6+AUEYYHC19ZHRsXELdQ1JYNUbKekUmeIAkLn5he3hUf5ri5tpHuhAA

馃槅 Thank you!

Was this page helpful?
0 / 5 - 0 ratings