jmarceli
jmarceli

Reputation: 20202

Flow default values type checking

I've got a problem with Flow type checking when I assigns default values with Object.assign. Here is an example:

type ConfigIn = {
  someValue?: number,
};

type Config = ConfigIn & {
  someValue: number,
};

function test(config: ConfigIn): number {
  // here Flow will report an error:
  // Cannot assign `Object.assign(...)` to `myConfig` because 
  // undefined [1] is incompatible with number [2] in property `someValue`.:
  const myConfig: Config = Object.assign({}, {
    someValue: 1000,
  }, config);

  return otherFunction(myConfig.someValue);
}

function otherFunction(input: number): number {
  return 123;
}

Here is a link to the online example: https://flow.org/try...

If I use ConfigIn type instead of Config everywhere I will get:

Cannot call `otherFunction` with `myConfig.someValue` bound to `input` 
because undefined [1] is incompatible with number [2].

Here is the link: https://flow.org/try...

What is a recommended way to solve this without using type any somewhere?

BONUS

What if my ConfigIn type has nested properties?

Example: https://flow.org/try...

Solution: This can be fixed by using Exact Object Types check this https://flow.org/try...

Upvotes: 1

Views: 696

Answers (1)

Xarvalus
Xarvalus

Reputation: 3021

Based on created issue #6616 on facebook/flow repository, wchargin suggested avoiding intersection operators (Type1 && Type2) because they tends to break more often.

Instead it's possible with type-spread operator:

type ConfigIn = {
  someValue?: number,
};

type Config = {
  ...ConfigIn, // spread instead intersection
  someValue: number,
};

function test(config: ConfigIn): number {
  const myConfig: Config = Object.assign({}, {
    someValue: 1000,
  }, config);

  return otherFunction(myConfig.someValue);
}

function otherFunction(input: number): number {
  return 123;
}

Try on: https://flow.org/try/...

Upvotes: 1

Related Questions