2016-12-17 71 views
11

我正在學習Flow,因此我正在使用JavaScript和Flow處理一個小型業餘愛好項目。我有一個類Foo和一個不同的類Bar,我想在一個Foo對象的數組中作爲構造函數的一個選項。但是,我也希望能夠爲每個這樣的對象發送一些其他數據,所以我想要一個數組,其中每個元素是一個普通的Foo對象或包裝在數組或對象中的Foo對象。無法將對象數組分配給Flow中的工會類型數組

但是,當我嘗試爲此編寫代碼時,出現了一些我不明白原因的奇怪錯誤。據我所知,它認爲存在類型衝突,因爲Foo不兼容所有的聯合類型,但據我瞭解,它應該只需要與其中至少一個兼容...

這裏是最少的代碼,我需要重現我得到了確切的錯誤(link to tryflow.org example):

// @flow 

class Foo { } 

interface BarOptions { 
    foos: (Foo | [ Foo ] | { foo: Foo })[];   // line 6 
} 

class Bar { 
    constructor(options?: BarOptions) { } 
} 

const foo: Foo = new Foo(); 

const bar = new Bar({ 
    foos: [ foo ],         // line 16 
}); 

我收到以下錯誤:

Line 6: 
    tuple type: This type is incompatible with Foo 
    object type: This type is incompatible with Foo 
Line 16: 
    tuple type: This type is incompatible with Foo 
    object type: This type is incompatible with Foo 

有沒有這些錯誤的直觀(或不直觀的)原因?

回答

2

我認爲BarOptions實際上應該是一個類型別名而不是接口。一個接口declares a type that classes can implement。接口不是數據類型,它們不應該有字段(包含數據)。

這裏一切正常,只要我們將interface BarOptions更改爲type BarOptions =即可。

或者你可以改變foo成爲一個getter函數:

interface BarOptions { 
    foos(): (Foo | [ Foo ] | { foo: Foo })[]; 
} 
2

你認爲這可能與這個開放的Github上ticket?如果我們將interface替換爲type,它將驗證:

// @flow 

class Foo { } 

type BarOptions ={ 
    foos: 
     Class<Foo> | 
     Foo | 
     Foo[] | 
     { foo: Foo } 
} 

class Bar { 
    constructor(options?: BarOptions) { } 
} 

const foo: Foo = new Foo(); 

const bar = new Bar({ 
    foos: Foo, 
// foos: foo, 
// foos: [foo], 
// foos: { foo: foo }, 
}); 
+0

您能解釋這可行嗎? (我的問題不是如何解決這個問題,它試圖理解爲什麼這是一個問題) – Frxstrem

+0

我不明白這兩者是如何不同的;正如我所理解的那樣,在這兩種情況下,'foo'都將被聲明爲相同類型('Foo'),唯一的區別是在第一行中,類型是隱式的,而第二行是顯式的。除非我錯誤地理解流類型的工作原理,否則我不會看到它們的行爲方式會有所不同(儘管看起來確實如此)。 – Frxstrem

+0

這個問題可能與此有關嗎? https://github.com/facebook/flow/issues/1569 –

相關問題