在 Flow 中键入"camel caser":差异问题?



尝试流链接

我一直在输入一个"camel-caser"函数(一个使用JSON并对其键进行camel-case处理的函数)。一路上我遇到了一些问题,我很好奇你们是否有什么建议。

骆驼案件审理者永远不会改变其论点的形式,所以我想保留我所传递的任何内容的类型;理想情况下,在一个数字数组上调用camelize会返回另一个数字阵列等。

我从以下内容开始:

type JSON = null | string | number | boolean | { [string]: JSON } | JSON[]
function camelize<J: JSON>(json: J): J {
throw "just typecheck please"
}

这对于简单的情况(nullstringnumberboolean)非常有效,但对于JSON字典或数组来说,效果并不理想。例如:

const dictionary: { [string]: number } = { key: 123 }
const camelizedDictionary = camelize(dictionary)

将失败,并出现类型错误。如果您传入一个值,例如键入number[],也会出现类似的问题。我想我理解这个问题:数组和字典是可变的,因此它们所指向的值的类型是不变的;一个数字数组是而不是JSON[]的子类型,因此Flow抱怨道。如果数组和字典是协变的,我相信这种方法会起作用。

考虑到它们不是协变的,你们对我应该如何看待这一点有什么建议吗?

Flow现在支持$ReadOnly$ReadOnlyArray,因此另一种方法是将JSON类型定义为

type JSON = 
| null 
| string 
| number 
| boolean 
| $ReadOnly<{ [string]: JSON }> 
| $ReadOnlyArray<JSON>

这解决了上述问题之一,因为$ReadOnlyArray<number>$ReadOnlyArray<JSON>的亚型。

这可能不起作用,这取决于camelize函数的实现,因为它可能会将键修改为驼色大小写。但是,了解Flow中的只读实用程序是很好的,因为它们功能强大,可以实现更简洁、可能更正确的函数类型。

使用属性方差来解决字典问题:

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类型:

type JSON = null | string | number | boolean | { +[string]: JSON } | Array<JSON> | Array<number>;

我在这里只添加了Array<number>来表明我的观点。显然,这很麻烦,尤其是如果您还想包含任意混合的JSON元素(如Array<string | number | null>)。但它有望解决共同的问题。

(我还将其更改为我更熟悉的数组语法,但功能上应该没有区别)。

有人说要添加Array的只读版本,它类似于协变对象类型,我相信它会解决您的问题。但到目前为止,还没有什么真正的结果

根据你给出的内容完成试用流程。

相关内容

  • 没有找到相关文章

最新更新