簡體   English   中英

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

[英]JS Flow: Is inheritance in Flow broken?

考慮一種情況,你有一個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()

運行時,代碼按預期記錄以下內容

fooA called
fooB called

所以Javascript理解new B().fooA()是類B的對象。但是Flow給出了以下錯誤消息:

Cannot call new B().fooA().fooB because property fooB is missing in A

該怎么辦? 我對一個解決方案感興趣,我不需要更改父類A,因為它是在npm包中定義的。 我可以改變B。

如果你輸入fooA方法作為返回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

因為您不想更改A類:另一種簡單的方法是鍵入B類的fooA函數以返回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!

函數fooA()返回“this”,它是“A”的一個實例。 如您所知,A類不知道方法fooB存在。 因此,Flow(正確地)指出A中缺少屬性fooB。

知道事實上,A的這個特定實例也是B的實例,但Flow無法推斷出這一點。 你必須告訴它fooA()返回的A是使用強制轉換的特定場景中的B實例。

將您的調用更改為(new B().fooA(): B).fooB()應解決Flow錯誤。

Javascript(sans Flow)並不關心這種語義。 當你在fooA()返回的對象上調用“fooB”時,它只是在對象中尋找一個名為“fooB”的方法,它恰好存在,所以它有效,盡管它更容易破壞重構。 流是有用的,因為它會強制您了解被拋出的類型,並在將來為這些問題提供編譯時檢查。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM