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

时间:2017-02-13 01:27:50

标签: javascript types ecmascript-6 flowtype dependent-type

说我有以下常量字符串:

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

这不会导致:

example

所以我的问题是:

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

2)是否有可能在流程中做依赖类型?那么,例如,我可以通过类型编码返回的字符串必须是传递给foo函数的相同字符串吗?

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

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

2 个答案:

答案 0 :(得分:11)

不要将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}
}

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

答案 1 :(得分:0)

找到了解决该问题的方法, 除了使用流类型推断外,我们还可以指定文字类型

export default const FOO:'FOO' = 'FOO'

然后在您可以用作的功能中

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

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