键入“骆驼套”。在流程中:方差问题? [英] Typing a "camel caser" in Flow: variance issues?
问题描述
我一直在打一个 camel caser函数(一个使用JSON和camel case的键的函数)。在此过程中,我遇到了一些问题,我很好奇大家是否有任何建议。
I've been messing around with typing a "camel caser" function (one that consumes JSON and camel cases its keys). I've run into a few issues along the way, and I'm curious if y'all have any suggestions.
骆驼保护者永远不会改变其论点的形式,因此我想保留传入的所有内容的类型;理想情况下,在一个数字数组上调用 camelize
会返回另一个数字数组,依此类推。
A camel caser never changes the shape of its argument, so I would like to preserve the type of whatever I pass in; ideally, calling camelize
on an array of numbers would return another array of numbers, etc.
我已经开始
type JSON = null | string | number | boolean | { [string]: JSON } | JSON[]
function camelize<J: JSON>(json: J): J {
throw "just typecheck please"
}
这对简单的情况非常有用,例如 null
, string
,数字
和布尔值
,但对于JSON字典或数组来说,效果并不理想。例如:
This works great for the simple cases, null
, string
, number
, and boolean
, but things don't quite work perfectly for JSON dictionaries or array. For example:
const dictionary: { [string]: number } = { key: 123 }
const camelizedDictionary = camelize(dictionary)
将失败,并出现类型错误。如果您输入例如 number []
的值,也会出现类似的问题。我认为我理解这个问题:数组和字典是可变的,因此它们指向的值的类型不变;数字数组不是 是 JSON []
的子类型,因此Flow抱怨。如果数组和字典是协变的,我相信这种方法会行得通。
will fail with a type error. A similar issue will come up if you pass in a value of, say, type number[]
. I think I understand the issue: arrays and dictionaries are mutable, and hence invariant in the type of the values they point to; an array of numbers is not a subtype of JSON[]
, so Flow complains. If arrays and dictionaries were covariant though, I believe this approach would work.
鉴于它们不是协变的,你们对我应该怎么做有什么建议吗?想想这个吗?
Given that they're not covariant though, do y'all have any suggestions for how I should think about this?
推荐答案
使用属性差异来解决字典问题:
Use property variance to solve your problem with dictionaries:
type JSON = null | string | number | boolean | { +[string]: JSON } | JSON[]
https://flowtype.org/blog/2016/10/04/Property-Variance.html
关于 Arrays
的问题,正如您所指出的那样,该问题与可变性有关。不幸的是, Array< number>
不是 Array< JSON>
的子类型。我认为,获得所需内容的唯一方法是显式枚举所有允许的 Array
类型:
As for your problem with Arrays
, as you've pointed out the issue is with mutability. Unfortunately Array<number>
is not a subtype of Array<JSON>
. I think the only way to get what you want is to explicitly enumerate all of the allowed Array
types:
type JSON = null | string | number | boolean | { +[string]: JSON } | Array<JSON> | Array<number>;
我只添加了 Array< number>
在这里说明我的观点。显然,这很麻烦,特别是如果您还希望包括JSON元素的任意混合(例如 Array< string | number | null>
)。但这有望解决常见问题。
I've added just Array<number>
here to make my point. Obviously this is burdensome, especially if you also want to include arbitrary mixes of JSON elements (like Array<string | number | null>
). But it will hopefully address the common issues.
(我也将其更改为我更熟悉的数组语法,但功能上应该没有区别)
(I've also changed it to the array syntax with which I am more familiar but there should be no difference in functionality).
有传言说要添加只读版本的 Array
,这类似于协变对象类型。 ,我相信它会在这里解决您的问题。但到目前为止,没有什么真的来了吧。
There has been talk of adding a read-only version of Array
which would be analogous to covariant object types, and I believe it would solve your problem here. But so far nothing has really come of it.
完整的尝试流基于您提供的内容。
Complete tryflow based on the one you gave.
这篇关于键入“骆驼套”。在流程中:方差问题?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!