如何用Flow描述Immutable.js地图形状 [英] How to describe Immutable.js Map shape with Flow

查看:80
本文介绍了如何用Flow描述Immutable.js地图形状的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想使用Immutable的流类型定义来描述地图的形状.

I would like to describe the shape of a map using Immutable's flow type definitions.

您可以通过以下方式描述对象的形状:

You can describe the shape of an object by:

const stateShape: {
  id: number,
  isActive: boolean
} = {
  id: 123,
  isActive: true
};

Immutable的地图有类似的东西吗?

Is there something similar for Immutable's Maps?

推荐答案

TL; DR;

否,但是使用Records可以让Flow对形状进行类型检查,而不是类型.

TL;DR;

No, but using Records you can get Flow to typecheck the shape but not the types.

正确的答案是:否,因为地图没有形状 (至少在Flow和Immutable中).但是 Immutable 确实具有带有形状的地图"类型.那就是记录.但是由于下面描述的原因(因为它并不严格相关),Immutable.Record的流libdef非常松散,实际上不检查形状.

The correct answer would be: no, since maps don't have shapes (at least in Flow and Immutable). But Immutable does have a type for "Maps" with shapes. That would be Records. But for reasons described below (since it's not strictly relevant) the flow libdef for Immutable.Record is very loose and actually doesn't check for shapes.

如果我们忽略直接访问Record属性的(可能是不必要的)功能,则可以创建更好的libdef.看起来像这样:

If we ignore the (arguably unnecessary) feature of directly accessing Record properties, we can create a better libdef. The would look like this:

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>;
}

通过此声明,我们可以定义记录的形状. 这是在行动.但是我们仍然不能定义实际值的类型. Flow确实定义了未记录的$PropertyType<T, K>类型.它带有一个对象T和一个字符串文字K.为了使$PropertyType在我们的情况下起作用,它需要为$Keys<T>(字符串联合类型)工作.几周前,出现了一个问题,使之成为现实. 可以在此处找到.

With this declaration we can define the shape of the Record. Here it is in action. But we still can't define the types of the actual values. Flow does define an undocumented $PropertyType<T, K> type. Which takes an object T and a string literal K. To make $PropertyType work in our case it would need to work for $Keys<T> which is a string union type. A few weeks ago an issue was opened to make this happen. It can be found here.

在流量上它们是完全不同的.这是一张地图:

In flow they are fairly different. This is a Map:

type MyMaps = { [key: string]: number }

实际密钥是未知的. Flow唯一了解的是,所有键都必须是字符串,而所有值都必须是数字.另一方面,对象类型看起来像:

The actual keys are unknown. The only thing Flow knows, is that all keys must be strings and all values must be numbers. An Object type on the other hand looks something like:

type MyObject = { a: string, x: boolean }

在创建或更改对象时,MyObject Flow类型的newObj将检查newObj.a是字符串,并且newObj.x是布尔值.

When creating or changing an object, newObj, of type MyObject Flow, will check that newObj.a is a string and newObj.x is a boolean.

一条记录通过直接键访问公开每个键/值对.

A Record exposes every key/value pair through direct key access.

type R = { a: string }
const r = Record({ a: 'Supa' })
r.a === r.get('a')

这将要求r的类型定义是Record<R>R的交集(不完全是,但是足够接近).所以:

This would require the type definition of r to be an intersect of Record<R> and R (not exactly, but it's close enough). So:

(r: R & Record<R>)

这不起作用,因为Flow缺乏对与对象相交类型的支持. 这里是如何看起来在行动.

This doesn't work because Flow lacks support for intersect types with objects. Here's how that looks in action.

这篇关于如何用Flow描述Immutable.js地图形状的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆