Skip to content

Instantly share code, notes, and snippets.

@leebyron
Last active July 9, 2018 04:13
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save leebyron/d94b159284644575906ac17cdc3e34a9 to your computer and use it in GitHub Desktop.
Save leebyron/d94b159284644575906ac17cdc3e34a9 to your computer and use it in GitHub Desktop.
flow-implements-bug
/* @flow */
interface SomeInterface {
method(): string
}
export class SomeClass implements SomeInterface {
static async load(): Promise<SomeClass> {
// There's no error here, as expected.
return new SomeClass()
}
method(): string {
return 'wow'
}
}
{
"dependencies": {
"flow-bin": "0.76.0"
}
}
/* @flow */
import { type SomeInterface } from './SomeInterface'
export class SomeClass implements SomeInterface {
static async load(): Promise<SomeClass> {
// This is returning an unexpected error. The only difference between this
// And BothInSameFile.js is that this has imported the interface from
// another file.
return new SomeClass()
}
method(): string {
return 'wow'
}
}
/* @flow */
export interface SomeInterface {
method(): string
}
@leebyron
Copy link
Author

leebyron commented Jul 9, 2018

Reported: facebook/flow#6576

git clone https://gist.github.com/d94b159284644575906ac17cdc3e34a9 flow-implements-bug
cd flow-implements-bug
npm install
npx flow check

Produces:

Error ┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈ SomeClass.js:10:12

SomeClass [1] is incompatible with Promise [2].

     SomeClass.js
       7│     // This is returning an unexpected error. The only difference between this
       8│     // And BothInSameFile.js is that this has imported the interface from
       9│     // another file.
 [1]  10│     return new SomeClass()
      11│   }
      12│
      13│   method(): string {

     /private/tmp/flow/flowlib_27e56be1/core.js
 [2] 613│ declare function $await<T>(p: Promise<T> | T): T;

@leebyron
Copy link
Author

leebyron commented Jul 9, 2018

Here's a --traces view:

npx flow check --traces=1000
Error ┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈ SomeClass.js:10:12

SomeClass [1] is incompatible with Promise [2].

     SomeClass.js
       7│     // This is returning an unexpected error. The only difference between this
       8│     // And BothInSameFile.js is that this has imported the interface from
       9│     // another file.
 [1]  10│     return new SomeClass()
      11│   }
      12│
      13│   method(): string {

     /private/tmp/flow/flowlib_2169e913/core.js
 [2] 613│ declare function $await<T>(p: Promise<T> | T): T;

Trace:
* path 1:
  5: export class SomeClass implements SomeInterface {
                                       ^^^^^^^^^^^^^ NullT [super of `Object`]
613: declare function $await<T>(p: Promise<T> | T): T;
                                   ^^^^^^^^^^ ~> ExtendsUseT [extends `Promise`] (from path 2). See lib: /private/tmp/flow/flowlib_2169e913/core.js:613
* path 2:
 38: declare class Object {
                   ^^^^^^ NullT [super of `Object`]. See lib: /private/tmp/flow/flowlib_2169e913/core.js:38
  5: export class SomeClass implements SomeInterface {
                                       ^^^^^^^^^^^^^ ~> ReposLowerT [super of `SomeInterface`] (from path 3)
* path 3:
 38: declare class Object {
                   ^^^^^^ NullProtoT [super of `Object`]. See lib: /private/tmp/flow/flowlib_2169e913/core.js:38
  5: export class SomeClass implements SomeInterface {
                                       ^^^^^^^^^^^^^ ~> ReposLowerT [super of `SomeInterface`] (from path 4)
* path 4:
  5: export class SomeClass implements SomeInterface {
                                       ^^^^^^^^^^^^^ InstanceT [super of `SomeInterface`]
613: declare function $await<T>(p: Promise<T> | T): T;
                                   ^^^^^^^^^^ ~> ExtendsUseT [extends `Promise`] (from path 5). See lib: /private/tmp/flow/flowlib_2169e913/core.js:613
* path 5:
  5: export class SomeClass implements SomeInterface {
                                       ^^^^^^^^^^^^^ OpenT [super of `SomeInterface`]
613: declare function $await<T>(p: Promise<T> | T): T;
                                   ^^^^^^^^^^ ~> ExtendsUseT [extends `Promise`] (from path 6). See lib: /private/tmp/flow/flowlib_2169e913/core.js:613
* path 6:
  5: export class SomeClass implements SomeInterface {
                                       ^^^^^^^^^^^^^ AnnotT [super of `SomeInterface`]
613: declare function $await<T>(p: Promise<T> | T): T;
                                   ^^^^^^^^^^ ~> ExtendsUseT [extends `Promise`] (from path 7). See lib: /private/tmp/flow/flowlib_2169e913/core.js:613
* path 7:
  5: export class SomeClass implements SomeInterface {
                                       ^^^^^^^^^^^^^ ObjProtoT [super of `SomeInterface`]
613: declare function $await<T>(p: Promise<T> | T): T;
                                   ^^^^^^^^^^ ~> ExtendsUseT [extends `Promise`] (from path 8). See lib: /private/tmp/flow/flowlib_2169e913/core.js:613
* path 8:
  3: export interface SomeInterface {
                      ^^^^^^^^^^^^^ ObjProtoT [super of `SomeInterface`]. See: SomeInterface.js:3
  5: export class SomeClass implements SomeInterface {
                                       ^^^^^^^^^^^^^ ~> ReposLowerT [`SomeInterface`] (from path9)
* path 9:
  5: export class SomeClass implements SomeInterface {
                                       ^^^^^^^^^^^^^ InstanceT [`SomeInterface`]
  5: export class SomeClass implements SomeInterface {
                                       ^^^^^^^^^^^^^ ~> UseT(UnknownUse, OpenT) [`SomeInterface`] (from path 10)
613: declare function $await<T>(p: Promise<T> | T): T;
                                   ^^^^^^^^^^ ~> ExtendsUseT [extends `Promise`] (from path 15).See lib: /private/tmp/flow/flowlib_2169e913/core.js:613
* path 10:
  3: export interface SomeInterface {
                      ^^^^^^^^^^^^^ InstanceT [`SomeInterface`]. See: SomeInterface.js:3
  5: export class SomeClass implements SomeInterface {
                                       ^^^^^^^^^^^^^ ~> UseT(UnknownUse, OpenT) [`SomeInterface`] (from path 11)
  5: export class SomeClass implements SomeInterface {
                                       ^^^^^^^^^^^^^ ~> ReposLowerT [`SomeInterface`] (from path14)
* path 11:
  3: import { type SomeInterface } from './SomeInterface'
                   ^^^^^^^^^^^^^ TypeT [Named import from module `./SomeInterface`]
  3: import { type SomeInterface } from './SomeInterface'
                   ^^^^^^^^^^^^^ ~> UseT(UnknownUse, OpenT) [Named import from module `./SomeInterface`] (from path 12)
  3: import { type SomeInterface } from './SomeInterface'
                   ^^^^^^^^^^^^^ ~> UseT(UnknownUse, OpenT) [Named import from module `./SomeInterface`] (from path 13)
  3: import { type SomeInterface } from './SomeInterface'
                   ^^^^^^^^^^^^^ OpenT [`SomeInterface`]
  5: export class SomeClass implements SomeInterface {
                                       ^^^^^^^^^^^^^ ~> UseT(UnknownUse, TypeT) [`SomeInterface`]
* path 12:
     v-------------------------------
  3: export interface SomeInterface {
  4:   method(): string
  5: }
     ^ ClassT [statics of `SomeInterface`]. See: SomeInterface.js:3
  3: import { type SomeInterface } from './SomeInterface'
                   ^^^^^^^^^^^^^ ~> ImportTypeT [Named import from module `./SomeInterface`] (from path 13)
* path 13:
     v-------------------------------
  3: export interface SomeInterface {
  4:   method(): string
  5: }
     ^ OpenT [export type interface SomeInterface = ...]. See: SomeInterface.js:3
  3: import { type SomeInterface } from './SomeInterface'
                                        ^^^^^^^^^^^^^^^^^ ~> UseT(UnknownUse, OpenT) [./SomeInterface]
  3: import { type SomeInterface } from './SomeInterface'
                   ^^^^^^^^^^^^^ ~> ImportNamedT [Named import from module `./SomeInterface`]
* path 14:
  5: export class SomeClass implements SomeInterface {
                                       ^^^^^^^^^^^^^ AnnotT [`SomeInterface`]
  5: export class SomeClass implements SomeInterface {
                  ^^^^^^^^^ ~> ImplementsT [`SomeClass`]
* path 15:
  5: export class SomeClass implements SomeInterface {
                                       ^^^^^^^^^^^^^ AnnotT [`SomeInterface`]
613: declare function $await<T>(p: Promise<T> | T): T;
                                   ^^^^^^^^^^ ~> ExtendsUseT [extends `Promise`] (from path 16).See lib: /private/tmp/flow/flowlib_2169e913/core.js:613
* path 16:
 10:     return new SomeClass()
                ^^^^^^^^^^^^^^^ NullT [super of `Object`]
613: declare function $await<T>(p: Promise<T> | T): T;
                                   ^^^^^^^^^^ ~> ExtendsUseT [extends `Promise`] (from path 17).See lib: /private/tmp/flow/flowlib_2169e913/core.js:613
* path 17:
 38: declare class Object {
                   ^^^^^^ NullT [super of `Object`]. See lib: /private/tmp/flow/flowlib_2169e913/core.js:38
 10:     return new SomeClass()
                ^^^^^^^^^^^^^^^ ~> ReposLowerT [super of `SomeClass`] (from path 18)
* path 18:
 38: declare class Object {
                   ^^^^^^ NullProtoT [super of `Object`]. See lib: /private/tmp/flow/flowlib_2169e913/core.js:38
 10:     return new SomeClass()
                ^^^^^^^^^^^^^^^ ~> ReposLowerT [super of `SomeClass`] (from path 19)
* path 19:
 10:     return new SomeClass()
                ^^^^^^^^^^^^^^^ InstanceT [super of `SomeClass`]
613: declare function $await<T>(p: Promise<T> | T): T;
                                   ^^^^^^^^^^ ~> ExtendsUseT [extends `Promise`] (from path 20).See lib: /private/tmp/flow/flowlib_2169e913/core.js:613
* path 20:
 10:     return new SomeClass()
                ^^^^^^^^^^^^^^^ OpenT [super of `SomeClass`]
613: declare function $await<T>(p: Promise<T> | T): T;
                                   ^^^^^^^^^^ ~> ExtendsUseT [extends `Promise`] (from path 21).See lib: /private/tmp/flow/flowlib_2169e913/core.js:613
* path 21:
 10:     return new SomeClass()
                ^^^^^^^^^^^^^^^ AnnotT [super of `SomeClass`]
613: declare function $await<T>(p: Promise<T> | T): T;
                                   ^^^^^^^^^^ ~> ExtendsUseT [extends `Promise`] (from path 22).See lib: /private/tmp/flow/flowlib_2169e913/core.js:613
* path 22:
 10:     return new SomeClass()
                ^^^^^^^^^^^^^^^ ObjProtoT [super of `SomeClass`]
613: declare function $await<T>(p: Promise<T> | T): T;
                                   ^^^^^^^^^^ ~> ExtendsUseT [extends `Promise`] (from path 23).See lib: /private/tmp/flow/flowlib_2169e913/core.js:613
* path 23:
  5: export class SomeClass implements SomeInterface {
                  ^^^^^^^^^ ObjProtoT [super of `SomeClass`]
 10:     return new SomeClass()
                ^^^^^^^^^^^^^^^ ~> ReposLowerT [`SomeClass`] (from path 24)
* path 24:
 10:     return new SomeClass()
                ^^^^^^^^^^^^^^^ InstanceT [`SomeClass`]
613: declare function $await<T>(p: Promise<T> | T): T;
                                   ^^^^^^^^^^ ~> ExtendsUseT [extends `Promise`] (from path 25).See lib: /private/tmp/flow/flowlib_2169e913/core.js:613
* path 25:
 10:     return new SomeClass()
                ^^^^^^^^^^^^^^^ InstanceT [`SomeClass`]
613: declare function $await<T>(p: Promise<T> | T): T;
                                   ^^^^^^^^^^ ~> UseT(Speculation, InstanceT) [`Promise`] (from path 26). See lib: /private/tmp/flow/flowlib_2169e913/core.js:613
* path 26:
613: declare function $await<T>(p: Promise<T> | T): T;
                                   ^^^^^^^^^^ InstanceT [`Promise`]. See lib: /private/tmp/flow/flowlib_2169e913/core.js:613
613: declare function $await<T>(p: Promise<T> | T): T;
                                   ^^^^^^^^^^ ~> ReposUseT [`Promise`] (from path 27). See lib: /private/tmp/flow/flowlib_2169e913/core.js:613
* path 27:
613: declare function $await<T>(p: Promise<T> | T): T;
                                   ^^^^^^^^^^ OpenT [`Promise`]. See lib: /private/tmp/flow/flowlib_2169e913/core.js:613
613: declare function $await<T>(p: Promise<T> | T): T;
                                   ^^^^^^^^^^ ~> ReposUseT [`Promise`] (from path 28). See lib: /private/tmp/flow/flowlib_2169e913/core.js:613
* path 28:
 10:     return new SomeClass()
                ^^^^^^^^^^^^^^^ InstanceT [`SomeClass`]
613: declare function $await<T>(p: Promise<T> | T): T;
                                   ^^^^^^^^^^ ~> UseT(Speculation, AnnotT) [`Promise`] (from path 29). See lib: /private/tmp/flow/flowlib_2169e913/core.js:613
* path 29:
 10:     return new SomeClass()
                ^^^^^^^^^^^^^^^ InstanceT [`SomeClass`]
613: declare function $await<T>(p: Promise<T> | T): T;
                                   ^^^^^^^^^^ ~> UseT(Speculation, TypeAppT) [`Promise`] (from path 30). See lib: /private/tmp/flow/flowlib_2169e913/core.js:613
* path 30:
613: declare function $await<T>(p: Promise<T> | T): T;
                                   ^^^^^^^^^^^^^^ ChoiceKitT Trigger [union type]. See lib: /private/tmp/flow/flowlib_2169e913/core.js:613
613: declare function $await<T>(p: Promise<T> | T): T;
                                   ^^^^^^^^^^^^^^ ~> UseT(UnknownUse, OpenT) [union type] (from path 31). See lib: /private/tmp/flow/flowlib_2169e913/core.js:613
613: declare function $await<T>(p: Promise<T> | T): T;
                                   ^^^^^^^^^^^^^^ ~> ChoiceKitUseT TryFlow [union type] (from path 36). See lib: /private/tmp/flow/flowlib_2169e913/core.js:613
* path 31:
  6:   static async load(): Promise<SomeClass> {
                            ^^^^^^^^^^^^^^^^^^ PolyT [`Promise`]
  6:   static async load(): Promise<SomeClass> {
                            ^^^^^^^^^^^^^^^^^^ ~> UseT(UnknownUse, OpenT) [`Promise`] (from path32)
  6:   static async load(): Promise<SomeClass> {
                            ^^^^^^^^^^^^^^^^^^ OpenT [`Promise`]
613: declare function $await<T>(p: Promise<T> | T): T;
                                   ^^^^^^^^^^^^^^ ~> ChoiceKitUseT FullyResolveType [union type](from path 34). See lib: /private/tmp/flow/flowlib_2169e913/core.js:613
* path 32:
  6:   static async load(): Promise<SomeClass> {
                            ^^^^^^^^^^^^^^^^^^ OpenT [.Promise]
  6:   static async load(): Promise<SomeClass> {
                            ^^^^^^^^^^^^^^^^^^ ~> UseT(UnknownUse, OpenT) [`Promise`] (from path33)
  6:   static async load(): Promise<SomeClass> {
                            ^^^^^^^^^^^^^^^^^^ ~> ReposLowerT [`Promise`]
* path 33:
OpenT [module]
~> UseT(UnknownUse, OpenT) [module]
  6:   static async load(): Promise<SomeClass> {
                            ^^^^^^^^^^^^^^^^^^ ~> GetPropT [`Promise`]
* path 34:
  6:   static async load(): Promise<SomeClass> {
                                    ^^^^^^^^^ InstanceT [`SomeClass`]
613: declare function $await<T>(p: Promise<T> | T): T;
                                   ^^^^^^^^^^^^^^ ~> ChoiceKitUseT FullyResolveType [union type](from path 35). See lib: /private/tmp/flow/flowlib_2169e913/core.js:613
* path 35:
  6:   static async load(): Promise<SomeClass> {
                                    ^^^^^^^^^ OpenT [`SomeClass`]
613: declare function $await<T>(p: Promise<T> | T): T;
                                   ^^^^^^^^^^^^^^ ~> ChoiceKitUseT FullyResolveType [union type](from path 36). See lib: /private/tmp/flow/flowlib_2169e913/core.js:613
* path 36:
 10:     return new SomeClass()
                ^^^^^^^^^^^^^^^ InstanceT [`SomeClass`]
613: declare function $await<T>(p: Promise<T> | T): T;
                                   ^^^^^^^^^^^^^^ ~> UseT(FunParam, UnionT) [union type] (from path 37). See lib: /private/tmp/flow/flowlib_2169e913/core.js:613
* path 37:
 10:     return new SomeClass()
                ^^^^^^^^^^^^^^^ InstanceT [`SomeClass`]
 10:     return new SomeClass()
                ^^^^^^^^^^^^^^^ ~> UseT(UnknownUse, OpenT) [new `SomeClass`] (from path 38)
 10:     return new SomeClass()
                ^^^^^^^^^^^^^^^ ~> ReposLowerT [new `SomeClass`] (from path 45)
* path 38:
  5: export class SomeClass implements SomeInterface {
                  ^^^^^^^^^ InstanceT [`SomeClass`]
 10:     return new SomeClass()
                ^^^^^^^^^^^^^^^ ~> ReposLowerT [new `SomeClass`] (from path 39)
* path 39:
 10:     return new SomeClass()
                ^^^^^^^^^^^^^^^ VoidT [undefined]
 10:     return new SomeClass()
                ^^^^^^^^^^^^^^^ ~> UseT(UnknownUse, OpenT) [new `SomeClass`] (from path 40)
 10:     return new SomeClass()
                ^^^^^^^^^^^^^^^ ~> ObjTestT [new `SomeClass`] (from path 42)
* path 40:
 10:     return new SomeClass()
                    ^^^^^^^^^ FunT [default constructor]
 10:     return new SomeClass()
                    ^^^^^^^^^ ~> UseT(UnknownUse, OpenT) [constructor return] (from path 41)
 10:     return new SomeClass()
                ^^^^^^^^^^^^^^^ ~> CallT [new `SomeClass`] (from path 41)
* path 41:
  5: export class SomeClass implements SomeInterface {
                  ^^^^^^^^^ InstanceT [`SomeClass`]
 10:     return new SomeClass()
                ^^^^^^^^^^^^^^^ ~> MethodT [new `SomeClass`] (from path 42)
* path 42:
 10:     return new SomeClass()
                    ^^^^^^^^^ ClassT [statics of `SomeClass`]
 10:     return new SomeClass()
                ^^^^^^^^^^^^^^^ ~> ConstructorT [new `SomeClass`] (from path 43)
* path 43:
 10:     return new SomeClass()
                    ^^^^^^^^^ ThisClassT [statics of `SomeClass`]
 10:     return new SomeClass()
                    ^^^^^^^^^ ~> UseT(AssignVar, OpenT) [`SomeClass`] (from path 44)
 10:     return new SomeClass()
                    ^^^^^^^^^ OpenT [`SomeClass`]
 10:     return new SomeClass()
                ^^^^^^^^^^^^^^^ ~> ConstructorT [new `SomeClass`]
* path 44:
  5: export class SomeClass implements SomeInterface {
                  ^^^^^^^^^ ThisClassT [statics of `SomeClass`]
  5: export class SomeClass implements SomeInterface {
                  ^^^^^^^^^ ~> UseT(AssignVar, OpenT) [`SomeClass`]
 10:     return new SomeClass()
                    ^^^^^^^^^ ~> ReposLowerT [`SomeClass`]
* path 45:
 10:     return new SomeClass()
         ^^^^^^^^^^^^^^^^^^^^^^ FunT [function type]
 10:     return new SomeClass()
                ^^^^^^^^^^^^^^^ ~> CallT [async return] (from path 46)
* path 46:
 10:     return new SomeClass()
         ^^^^^^^^^^^^^^^^^^^^^^ OpenT [.$await]
 10:     return new SomeClass()
         ^^^^^^^^^^^^^^^^^^^^^^ ~> UseT(UnknownUse, OpenT) [async return] (from path 47)
 10:     return new SomeClass()
                ^^^^^^^^^^^^^^^ ~> CallT [async return]
* path 47:
OpenT [module]
~> UseT(UnknownUse, OpenT) [module]
 10:     return new SomeClass()
         ^^^^^^^^^^^^^^^^^^^^^^ ~> GetPropT [async return]



Found 1 error

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment