JS Flow:流程中的继承是否破裂?

Cle*_*ens 5 javascript inheritance flowtype

考虑一种情况,你有一个B类从A类扩展.你创建一个B类型的对象,并调用A中定义的方法fooA,然后调用B中定义的方法fooB.

class A {
  fooA () {
    console.log('fooA called')
    return this
  }
}

class B extends A {
  fooB () {
    console.log('fooB called')
    return this
  }
}

new B().fooA().fooB()
Run Code Online (Sandbox Code Playgroud)

运行时,代码按预期记录以下内容

fooA called
fooB called
Run Code Online (Sandbox Code Playgroud)

所以Javascript理解这new B().fooA()是B类的对象.但是Flow给出了以下错误消息:

Cannot call new B().fooA().fooB because property fooB is missing in A
Run Code Online (Sandbox Code Playgroud)

该怎么办?我对一个解决方案感兴趣,我不需要更改父类A,因为它是在npm包中定义的.我可以改变B.

Jam*_*aus 1

如果您将该fooA方法键入为 returned this,则 Flow 会理解任何扩展该类的类A也将从该方法返回其自身的实例:

尝试

class A {
  fooA (): this {
    console.log('fooA called')
    return this
  }
}

class B extends A {
  fooB () {
    console.log('fooB called')
    return this
  }
}

new B().fooA().fooB() // No error
Run Code Online (Sandbox Code Playgroud)

由于您不想更改A类:实现此功能的另一种简单方法是键入类fooA的函数B以返回 的实例B

尝试

class A {
  fooA () {
    console.log('fooA called')
    return this
  }
}

class B extends A {
  fooB () {
    console.log('fooB called')
    return this
  }
  fooA: () => B; // Hey Flow, this actually returns a B
}

new B().fooA().fooB() // No error!
Run Code Online (Sandbox Code Playgroud)