2016-08-09 45 views
4

強制香草JS對象和流的數據結構是容易的:更簡單的方法來執行類型不可變的數據結構?

type ExampleObjType = { 
    key1: number, 
    key2: string 
}; 

const obj: ExampleObjType = { 
    key1: 123, 
    key2: '123' 
}; 

看起來這需要不必要的大量的樣板以執行在不可變的類似結構:

type TestSpec = { 
    key1: number, 
    key2: string, 
}; 

const TestRecord = Record({ 
    key1: 0, 
    key2: '', 
}); 

const record: TestSpec & Record<TestSpec> = new TestRecord({ 
    key1: 123, 
    key2: '123', 
}); 

此外,上述結構有一些主要缺陷:

  • 強制默認值
  • 在初始化時,只有訪問

理想我想能夠使用Immutable.Map,像這樣的無效鍵無執法:

type TestSpec = Map<{key1: number, key2: number}>; 

const testMap: TestSpec = Map({ 
    key1: 123, 
    key2: '123', 
}); 

然而,目前的實現只允許鍵和值打字類型。我可以使用諸如type Key = 'key1' | 'key2'之類的東西來限制鍵的類型,但是我仍然不能明確地鍵入每個鍵的值。

有沒有辦法通過Immutable完成我在尋找的東西?對於真正的類型安全來說,這似乎是一個非常基礎的要求,特別是當用於Redux動作有效載荷時。

回答

6

immutable.Record()很難打字。其實,it's currently typed返回any。一方面,這是不方便的,因爲您需要從頭開始描述TestRecord的類型。另一方面,它可以讓你輸入它,但是你喜歡!

這裏有一個選項:

interface TestSpec { 
    constructor(defaults: $Shape<TestSpec>): void, 
    key1: number, 
    key2: string, 
}; 

const TestRecord: Class<TestSpec> = Record({ 
    key1: 0, 
    key2: '', 
}); 

Class<TestSpec>類型是類誰的情況下,有型TestSpec的類型。您不必在TestSpec中定義構造函數,但通過這樣做,Flow將確保obj在看到new TestRecord(obj)時具有正確的時間。

(注:$Shape<TestSpec>是一個對象可能有也可能沒有的類型所以在這種情況下,它基本上意味着{key1?: number, key2?: string}。)

new TestRecord({key1: 123, key2: '123'}); // OK 
new TestRecord({key1: 123}); // OK 
new TestRecord({key2: '123'}); // OK 

new TestRecord({key2: 123}); // Error number -> string 
new TestRecord({key1: '123'}); // Error string -> number 
new TestRecord({key1: 123, key2: '123', key3: 'blah'}); // Error unknown property key3 

和流量將檢查實例屬性有正確的類型

const record = new TestRecord({key1: 123, key2: '123'}); 
(record.key1: string); // Error number -> string 
(record.key2: number); // Error string -> number 

Try this code on flowtype.org/try

相關問題