是否可以将流类型包装在不可变容器中?

时间:2016-06-21 18:31:32

标签: javascript immutable.js flowtype

例如,给出以下记录:

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>之类的内容,我认为这些内容与使用Flow类型系统的Immutable.js有所不同。

1 个答案:

答案 0 :(得分:3)

通常,这是不可能的,因为记录和映射具有非常不同的语义。地图类型使用键和值的类型进行参数化,因此当您调用var list = this.getView().byId("list"); jQuery.each(list.getList(), function(idx, item) { if (items.getBindingContext().getPath = sBindingPath) { list.setSelectedItem(item); } }); 时,所有键都将获得相同的类型。

但是有一种解决方法:

.get

使用某种脚本生成此类声明可能是一个好主意,以支持所需数量的键值对。

这种声明有点冗长,但如果你不搞乱类型参数,那就很安全。几条评论:

  • 我们使用最近的Flow功能,允许我们声明默认类型参数,以便我们可以对任意数量的键值对使用单个声明;

  • 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>类型的实际键来检索值;这有助于在某种程度上保持一致性,遗憾的是,我发现无法验证值类型的一致性,因此您必须小心这些。