2

在流動結構亞型可能會導致信息丟失:流的信息損失與這種多態性固有的結構分型有關嗎?

type O = {x: number, y: number}; 
type P = {x: number, y: number, z: number} 

function f(o: O) { 
    return o.x * 2, o.y * 2, o; 
} 

const p: P = {x: 2, y: 3, z: 100}; 
const r = f(p); 

r.z // type error (property not found) 

(。這段代碼是可怕的,因爲它執行可見突變只用於說明目的)

我讀過該行多態性是一種避免信息丟失而不危害型安全的概念。

有沒有辦法實現與亞型多態性一樣嗎?

[編輯]

爲了應對更大的觀衆我公司提供的有些嚇人術語的簡要說明:

  • Polymorpishm僅僅是一個奇特的詞語,以確定如果兩個類型等效的,即它使剛性型系統更靈活
  • 參數多態(在流泛型)指出,兩種類型是始終相當於,因爲類型並不在所有問題
  • 亞型多態性(子類型的流量)指出,兩種類型是等價的,如果你可以從他們那裏獲得一個層次,即歸入其超
  • 行多態性下的亞型類似於亞型,但解決了信息丟失的問題(在技術上,然而,沒有亞型的關係了,所以它不是子類型的一種形式)
  • 界多態性指出兩種等價爲特定目的只有,例如平等,秩序,映射等

回答

2

對於我已閱讀關於Flowtype我很確定你的功能是問題。

如果你這樣做,而不是:

function f<T: O>(o: T): T { 
    o.x *= 2; 
    o.y *= 2; 
    return o; 
} 

r.z; // okay 

這工作,因爲有限的多態性。現在身體類型根據T是O的子類型的假設進行檢查。此外,呼叫站點之間沒有信息丟失。 Read more about it here.

另外,我沒有聽說過排多態性之前,讓我去,並看着它。雖然看着它我看了幾件事情,似乎表明該行多態性子類型。 123

爲了擴大對這個答案並澄清爲何有機磷農藥功能不工作,但我提出了一個將正常工作。 T his is a nice reference as well but is specific to Java

通過具有該功能爲:

function f(o: O) { 
    return o.x * 2, o.y * 2, o; 
} 

該函數指定它明確地尋找O型的對象,而不是的O的對象或O-的子類型是允許的。在OP函數中,我們將參數o向下轉換爲類型O,而不是使用泛型(這很糟糕)。來處理這個正確的方法是利用泛型指定它可以是類型O或O的亞型,其可如下進行:

function f<T: O> (o: T): T { 
    o.x *= 2; 
    o.y *= 2; 
    return o; 
} 

Check out the docs on how flow handles generics以及它是如何與功能參數,對象等。

相關部分是:

  • 「泛型可以守住更具體的類型,同時增加了約束這樣的泛型類型作爲‘邊界’。

  • 「泛型有時讓你在這樣的參數類型傳遞給一個函數。這些被稱爲參數化泛型(或參數多態)。」 link

+0

爲什麼我的函數問題?它只是依賴於子類型的承諾,人們可以在一個亞型通過無論其超預期。你的建議是使用有界多態,相反,這只是意味着子類型不如其他形式的多態 - 至少在某些情況下以及實現可靠算法所需的複雜性。 – ftor

+0

@ftor我明白你在說什麼,看起來它應該工作,但是對於你所說的函​​數,你說它明確地尋找O類型的參數,而不是O類型的參數或O的子類型。指定參數是你告訴編譯器,你期待一個參數類型O或子類型O.查看Java如何處理它https://softwareengineering.stackexchange.com/questions/227918/java-use-polymorphism-or-bounded -type-parameters – kyle

+0

@ftor檢查我更新的答案,因爲它更好地解釋了我以前的評論和OOP,但在流程的上下文中。 – kyle