具有常量字符串和依赖类型的流类型

flow types with constant strings, and dependent types

假设我有以下常量字符串:

export default const FOO = 'FOO'

假设我将其导入到流注释文件中,如下所示:

import FOO from '../consts/Foo'

然后我有一个功能:

const example = (foo : string) : {| type: FOO, foo: string |} => {
  return {type: FOO, foo: foo}
}

这不是类型检查:

  6: const example = (foo : string) : {| type: FOO, foo: string |}=> {
                                                         ^^^^^^^^^^^^^^ string. Ineligible value used in/as type annotation (did you forget 'typeof'?)
  6: const example = (foo : string) : {| type: FOO, foo: string |}=> {
                                                         ^^^^^^^^^^^^^^ FOO

所以我的问题是:

1) 是否可以在流类型中使用常量,如何重现此行为?

2) 是否可以在流中做依赖类型?因此,例如,我可以通过类型进行编码,使 returned 的字符串必须与传递到 example 函数的字符串相同吗?

编辑:对第 2 部分的澄清:是否有可能以某种方式表明传递给 example 函数的 foo 参数实际上与 [=] 处的字符串相同return 对象中的 15=] 键?或者断言输入和输出具有相同的长度(比如移位密码函数)。或者说包含相同字符的排列? (洗牌)。

https://en.wikipedia.org/wiki/Dependent_type

不是将 FOO 声明为 const,而是将其声明为只有一个分支的不相交联合:

type FOO = "FOO"

那么你的代码可以这样更新:

const example = (foo : string) : {| type: FOO, foo: string |} => {
  return {type: "FOO", foo: foo}
}

如果您在需要 FOO 的地方使用除确切的字符串文字 "FOO" 之外的任何值,则会出现编译错误。

如果您希望保持不变,则需要以不同的方式命名类型,因为它们会发生冲突。所以你可以这样做:

const FOO = "FOO"
type FooType = "FOO";

const example = (foo : string) : {| type: FooType, foo: string |} => {
  return {type: FOO, foo: foo}
}

不幸的是,我找不到避免重复字符串文字的方法,因为类型不相交的联合定义语法只允许文字和类型,而不是变量,即使它们是常量。

已找到该问题的解决方法, 我们可以指定文字类型

而不是使用流类型推断
export default const FOO:'FOO' = 'FOO'

然后在函数中你可以使用 as

const example = (foo : string) : {| type: typeof FOO, foo: string |} => {
return {type: FOO, foo: foo}
}

因为当你声明常量类型时也被推断为字符串我相信流不支持从变量或常量设置类型定义。