我想用Immutable的流类型定义来描述地图的形状.
您可以通过以下方式描述对象的形状:
const stateShape: {
id: number,
isActive: boolean
} = {
id: 123,
isActive: true
};
Run Code Online (Sandbox Code Playgroud)
Immutable的地图有类似的东西吗?
Kri*_*tig 30
不,但是使用记录你可以获得Flow来检查形状而不是类型.
将正确的答案是:不,因为地图不具有形状 (至少在流量和不可变的).但是Immutable确实有一个带有形状的"地图"类型.这将是记录.但由于下面描述的原因(因为它并不严格相关),流程libdef Immutable.Record非常松散,实际上并不检查形状.
如果我们忽略直接访问Record属性的(可以说是不必要的)特性,我们可以创建一个更好的libdef.看起来像这样:
declare class Record<T: Object> {
static <T: Object>(spec: T, name?: string): Record<T>;
get: <A>(key: $Keys<T>) => A;
set<A>(key: $Keys<T>, value: A): Record<T>;
remove(key: $Keys<T>): Record<T>;
}
Run Code Online (Sandbox Code Playgroud)
通过此声明,我们可以定义Record的形状.这是在行动.但是我们仍然无法定义实际值的类型.Flow确实定义了一个未记录的$PropertyType<T, K>类型.它接受一个对象T和一个字符串文字K.为了$PropertyType在我们的案例中工作,它需要工作为$Keys<T>字符串联合类型.几个星期前,为了实现这一目标,已经开启了一个问题.它可以在这里找到.
在流程中他们是完全不同的.这是一张地图:
type MyMaps = { [key: string]: number }
Run Code Online (Sandbox Code Playgroud)
实际的密钥是未知的.Flow知道的唯一事情是所有键必须是字符串,所有值必须是数字.另一方面,对象类型看起来像:
type MyObject = { a: string, x: boolean }
Run Code Online (Sandbox Code Playgroud)
在创建或更改Flow newObj类型的对象时,MyObject将检查该newObj.a字符串newObj.x是否为布尔值.
记录通过直接密钥访问公开每个键/值对.
type R = { a: string }
const r = Record({ a: 'Supa' })
r.a === r.get('a')
Run Code Online (Sandbox Code Playgroud)
这将要求类型定义为和(不完全相同,但足够接近)r的交叉.所以:Record<R>R
(r: R & Record<R>)
Run Code Online (Sandbox Code Playgroud)
这不起作用,因为Flow缺少对具有对象的交叉类型的支持.这是看起来如何行动.
| 归档时间: |
|
| 查看次数: |
7338 次 |
| 最近记录: |