2017-01-16 64 views
1

Try flow link.是否有可能改進有界多態類型?

這裏是不工作我期望它的方式簡單的有界多態性例如:

// @flow 

function thisBreaks<T: 'a' | 'b'>(x: T): T { 
    if (x === 'a') { 
    return 'a' 
    } else { 
    return 'b' 
    } 
} 

function thisWorks<T: 'a' | 'b'>(x: T): T { 
    return x 
} 

const a = 'a' 
const aPrime: 'a' = thisWorks(a) 
const b = 'b' 
const bPrime: 'b' = thisWorks(b) 

5:  return 'a'    
      ^string. This type is incompatible with the expected return type of 
3: function thisBreaks<T: 'a' | 'b'>(x: T): T { 
^some incompatible instantiation of `T` 

7:  return 'b'    
      ^string. This type is incompatible with the expected return type of 
3: function thisBreaks<T: 'a' | 'b'>(x: T): T { 
^some incompatible instantiation of `T` 

我本來期望的第一個例子來工作,因爲如x === 'a'支票可能會提煉T'a',對不對?

+0

雖然這是不可能的,但你可能能夠完成你想要做的功能交叉點。我創建了一個工作類型爲你的函數:[嘗試流鏈路(https://flow.org/try/#0PQKgBAAgZgNg9gdzCYAoVBjOA7AzgFzCjjgC4wAKCgD3IHIBDOgSjAF4A+MRl1MfgQIBklGvQBGLdlzqTmqNqOrSwytuu5MwAfk10wEluQbYAnvMw4CYcQwBO9LYuJwKPeVjyFbAL0PsiEjc5Sy8iBgBLGFxHfWcg2V4gA) – Andy

回答

2

這是不可能的,應該是不可能的。下面是說明爲什麼一個例子:

function test<T: number | string>(x: T): T { 
    if (typeof x === 'number') { 
    return 1; 
    } else { 
    return 'b' 
    } 
} 

test((5: 5)); 

功能應該返回5類型的值,而是返回1代替。

那麼,會發生什麼?我們有一些未知類型T,我們知道T <:string | numberTstring | number的子類型)。在我們完善x之後,我們知道Tnumber的子類型。這並不意味着Tnumber。它可以是5,如示例中所示,或1 | 2 | 3。知道Tnumber的子類型不足以創建值T。要做到這一點,我們需要知道T的下限,但無法知道它。

最後一個問題是:爲什麼你的例子顯然是安全的呢?這很簡單:如果T <:'a',那麼它只能是'a'(或empty,但它並不重要)。沒有其他亞型'a'。因此,理論上,Flow可以支持這一點,但它不是很實用:如果你知道x'a',那麼比你可以只返回x

+0

謝謝!是的,我看到你對https://github.com/facebook/flow/issues/3219的迴應。我絕對沒有想到這些具體類型的含義。 –

+0

激發我的問題的實際問題在這裏:http://stackoverflow.com/questions/41496896/typing-a-camel-caser-in-flow-variance-issues。我說得對,沒有一種好的方法可以使駝峯變成精確的流量類型嗎? –

+0

對。生產T型產品的唯一方法是採取已經具有T型的東西。 – vkurchatkin

相關問題