2017-02-13 10 views
11

Скажем, у меня есть следующий постоянной строки:типы потоков с постоянными строками и зависимые типы

export default const FOO = 'FOO'

Say импортировать это в аннотированный файл потока следующим образом:

import FOO from '../consts/Foo'

Затем у меня есть функция:

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

Это не typecheck с:

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?

EDIT: Разъяснение к части 2: Можно ли каким-то образом указать, что параметр foo передается в функцию example фактически та же самая строка как строка в foo ключ в обратном объекте? Или утверждать, что вход и выход имеют одинаковую длину (например, функцию сдвигового шифра). Или сказать, содержат перестановку одних и тех же символов? (для перетасовки).

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

+0

Если вы хотите, чтобы 'FOO' имел тип' 'FOO'', вам нужно объявить его, иначе это просто строка. Для объектов, вы должны сделать «type: typeof FOO», как говорит ошибка. Хотя я не совсем уверен, что вы спрашиваете в своем 2) пункте. Тогда вы получите объект с двумя свойствами с тем же строковым значением. – loganfsmyth

ответ

5

Вместо того, чтобы объявить 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} 
} 

К сожалению, я не могу видеть способ избежать дублирований строкового литерала, поскольку типа синтаксис непересекающегося определения объединения допускает только литералы и тип, а не переменные, даже если они являются постоянными.

+0

для стандартного шаблона действия Flux для определения типов действий в виде строк для очистки некоторых ковычек от кода, это очень интересный шаблон. Таким образом, и исправьте меня, если я ошибаюсь, я могу определить мета-тип 'ValidResponses = FOO | BAR; 'и убедитесь, что вызов функции API возвращает правильный ответ, а не только правильный тип данных. – ermik

 Смежные вопросы

  • Нет связанных вопросов^_^