Типы потоков с постоянными строками и зависимые типы
Скажем, у меня есть следующая константная строка:
export default const FOO = 'FOO'
Скажем, я импортирую это в потоковом аннотированном файле так:
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
Ответы
Ответ 1
Вместо объявления 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}
}
К сожалению, я не вижу способа избежать дублирования строкового литерала, потому что синтаксис типа disjoint union определяет только литералы и типы, а не переменные, даже если они являются константами.