web-dev-qa-db-ja.com

定数文字列を持つフロータイプ、および依存型

次の定数文字列があるとします。

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)フローで依存型を実行することは可能ですか?たとえば、返される文字列がexample関数に渡される文字列と同じである必要があることを型を介してエンコードできますか?

編集:パート2の明確化:foo関数に渡されたexampleパラメーターが実際には戻りオブジェクトのfooキーの文字列と同じ文字列であることを何らかの方法で示すことは可能ですか?または、入力と出力の長さが同じであることを表明します(たとえば、シフト暗号関数)。または、同じ文字の順列が含まれていると言いますか? (シャッフル用)。

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

18
Abraham P

FOOconstとして宣言する代わりに、ブランチが1つだけの非交和として宣言します。

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

残念ながら、文字列リテラルの重複を回避する方法がわかりません。型非交和ユニオン定義構文では、定数であっても変数ではなく、リテラルと型のみが許可されるためです。

11
Peter Hall