Flow: Error message doesn't say where type mismatch happens

Created on 27 Jul 2017  路  7Comments  路  Source: facebook/flow

See https://flow.org/try/#0PQKgBAAgZgNg9gdzCYAoVAXAngBwKZgCCYAvGAN5jb4BcYA5AIb1gC+muBAQqRVZ3XoAjFu1RQArgDsAxhgCWcKWAAmcAMpwAtngwALeVIDmACkZ1CASgqoxMpQGcMYIXR5lK1PIJFt0azR19Q1MhSyA

Flow tells me there is a type mismatch, and the error message points me to the definition of type A and type B and tells me why they don't match up. What it doesn't tell me is where the mismatch happens. In a large codebase, it can be hard to track down the exact point where I'm passing the wrong object type, especially in a codebase that relies on type inference instead of annotating all the types explicitly. So in this flow try example, it would be great if the error message can also point me to line 11, where the actual error is generated.

error messages

Most helpful comment

Fixed in master!

Error: index.js:9
  9: doSomething(b)
                 ^ object type. This type is incompatible with the expected param type of
  4: function doSomething(a: A) {
                             ^ object type
  Property `type` is incompatible:
      1: export type A = { type: 'a' }
                                 ^^^ string literal `a`. Expected string literal `b`, got `a` instead. See: typeA.js:1
      1: export type B = { type: 'b' }
                                 ^^^ string literal `b`. See: typeB.js:1

Error: index.js:9
  9: doSomething(b)
                 ^ object type. This type is incompatible with the expected param type of
  4: function doSomething(a: A) {
                             ^ object type
  Property `type` is incompatible:
      1: export type B = { type: 'b' }
                                 ^^^ string literal `b`. Expected string literal `a`, got `b` instead. See: typeB.js:1
      1: export type A = { type: 'a' }
                                 ^^^ string literal `a`. See: typeA.js:1

All 7 comments

I have run your code on my local machine and get the following output :

src/first-test.js:11
 11: doSomething(b)
     ^^^^^^^^^^^^^^ function call
  3: type A = { type: 'a' }
                      ^^^ string literal `a`. Expected string literal `b`, got `a` instead
  4: type B = { type: 'b' }
                      ^^^ string literal `b`

src/first-test.js:11
 11: doSomething(b)
     ^^^^^^^^^^^^^^ function call
  4: type B = { type: 'b' }
                      ^^^ string literal `b`. Expected string literal `a`, got `b` instead
  3: type A = { type: 'a' }
                      ^^^ string literal `a`


Found 2 errors

Flow is showing an error line 11, as you expected.
The issue seems to come from the output of flow website editor and not the tool itself.

Oh that's interesting. I'll come up with a more complicated example and test it locally. I do run into this issue quite a lot, just need to find a minimal reproduction

Ok I've managed to reproduce locally as well. All I needed to do was move the type definitions out into separate files:

// typeA.js

// @flow

export type A = { type: 'a' }


// typeB.js

// @flow

export type B = { type: 'b' }


// index.js

// @flow

import type { A } from './typeA'
import type { B } from './typeB'

function doSomething(a: A) {
}

const b: B = { type: 'b' }

doSomething(b)

@g3r4n can you check again?

Correct.
Output look like that :

src/flow-4474/typeA.js:3
  3: export type A = { type: 'a' }
                             ^^^ string literal `a`. Expected string literal `b`, got `a` instead
  3: export type B = { type: 'b' }
                             ^^^ string literal `b`. See: src/flow-4474/typeB.js:3

src/flow-4474/typeB.js:3
  3: export type B = { type: 'b' }
                             ^^^ string literal `b`. Expected string literal `a`, got `b` instead
  3: export type A = { type: 'a' }
                             ^^^ string literal `a`. See: src/flow-4474/typeA.js:3


Found 2 errors

I'm not a flow expert, but i will investigate.

This is another case of an error message that's at the wrong location and too low-level. Flow should be able to back up and explain that the function argument doesn't match the signature rather than giving us the error inside where it's trying to unify A and B.

Fixed in master!

Error: index.js:9
  9: doSomething(b)
                 ^ object type. This type is incompatible with the expected param type of
  4: function doSomething(a: A) {
                             ^ object type
  Property `type` is incompatible:
      1: export type A = { type: 'a' }
                                 ^^^ string literal `a`. Expected string literal `b`, got `a` instead. See: typeA.js:1
      1: export type B = { type: 'b' }
                                 ^^^ string literal `b`. See: typeB.js:1

Error: index.js:9
  9: doSomething(b)
                 ^ object type. This type is incompatible with the expected param type of
  4: function doSomething(a: A) {
                             ^ object type
  Property `type` is incompatible:
      1: export type B = { type: 'b' }
                                 ^^^ string literal `b`. Expected string literal `a`, got `b` instead. See: typeB.js:1
      1: export type A = { type: 'a' }
                                 ^^^ string literal `a`. See: typeA.js:1
Was this page helpful?
0 / 5 - 0 ratings

Related issues

ghost picture ghost  路  3Comments

glenjamin picture glenjamin  路  3Comments

marcelbeumer picture marcelbeumer  路  3Comments

Beingbook picture Beingbook  路  3Comments

pelotom picture pelotom  路  3Comments