2016-06-21 43 views
13

例如,给出以下记录:是否有可能将流类型包装在不可变容器中?

type UserRecord = { 
    id: string; 
    name: ?string; 
    age: number; 
} 

有一些方法做以下等效:

/* @flow */ 

import { List, Map } from 'immutable' 

const users: List<Map<UserRecord>> = List();  
let user: Map<UserRecord>; 

user = Map({ id: '666', age: 30 }); 
users.push(user); 

否则我最终只是使用类似Map<string, any>我想带走从使用Immutable.js和Flow类型系统。

+0

请注意,有一个WIP immutable.js流接口,您需要手动将其包含到您的项目中。我不知道它是否运作良好,或者根本不知道。请参阅https://github.com/facebook/immutable-js/blob/master/type-definitions/immutable.js.flow和https://github.com/facebook/immutable-js/issues/203 – Nikita

回答

2

一般来说这是不可能的,因为记录和地图具有非常不同的语义。地图类型是使用键和值的类型进行参数化的,所以当您拨打.get时,您将获得所有键的相同类型。

周围有办法,但:

declare class Map<T, K1=null, V1=null, K2=null, V2=null> { 

    constructor(val: T): void; 

    get(key: K1 & $Keys<T>): V1; 
    get(key: K2 & $Keys<T>): V2; 
    // etc 
} 

const m: Map<{ foo: string, bar: number }, 'foo', string, 'bar', number> = new Map({ 
    'foo': 'foo', 
    bar: 42 
}); 


m.get('foo') // string 
m.get('bar') // number 
m.get('baz') // error 

这可能是一个好主意,产生这样的声明带有某种脚本的支持键值对所需量。

这样的声明有点冗长,但是如果你不弄乱类型参数,它是安全的。一对夫妇的意见:

  • 我们用最近的流量功能,让我们来声明默认类型参数,这样我们就可以使用任意数量的键值对的单笔申报;

  • K1 & $Keys<T>确保我们只能使用T类型的实际密钥来检索值;这在一定程度上有助于一致性,但不幸的是,我发现无法验证值类型的一致性,所以您必须小心这些。

+0

这很不幸对我们来说没有什么冗余的可用 - 感谢有趣的解决方法 – gf3

相关问题