Ответ 1
TL; DR;
Нет, но используя записи, вы можете получить Flow для typecheck формы, но не типы.
полной формы
Правильный ответ: нет, поскольку карты не имеют форм (по крайней мере, в потоке и неизменяемом). Но Immutable имеет тип "Карты" с фигурами. Это будет Записи. Но по причинам, описанным ниже (поскольку это не очень важно) поток libdef для Immutable.Record
очень свободен и фактически не проверяет формы.
Лучшая запись libdef
Если мы игнорируем (возможно ненужную) функцию прямого доступа к свойствам записи, мы можем создать лучший libdef. Это будет выглядеть так:
declare class Record<T: Object> {
static <T: Object>(spec: T, name?: string): Record<T>;
get: <A>(key: $Keys<T>) => A;
set<A>(key: $Keys<T>, value: A): Record<T>;
remove(key: $Keys<T>): Record<T>;
}
С помощью этого объявления мы можем определить форму записи. Здесь он находится в действии. Но мы все еще не можем определить типы фактических значений. Flow определяет недокументированный тип $PropertyType<T, K>
. Который берет объект T
и строковый литерал K
. Чтобы сделать $PropertyType
работать в нашем случае, ему нужно будет работать для $Keys<T>
, который является типом объединения строк. Несколько недель назад была открыта проблема, чтобы это произошло. Здесь можно найти.
Разница между Map и Object
В потоке они довольно разные. Это карта:
type MyMaps = { [key: string]: number }
Фактические ключи неизвестны. Единственное, что Flow знает, состоит в том, что все ключи должны быть строками, а все значения должны быть числами. С другой стороны, тип объекта выглядит примерно так:
type MyObject = { a: string, x: boolean }
При создании или изменении объекта newObj
типа MyObject
Flow проверяет, что newObj.a
является строкой, а newObj.x
является логическим.
Почему текущее определение так свободно
A Запись предоставляет каждую пару ключ/значение через прямой доступ к ключам.
type R = { a: string }
const r = Record({ a: 'Supa' })
r.a === r.get('a')
Это потребует определения типа r
как пересечения Record<R>
и r
(не совсем, но достаточно близко). Итак:
(r: R & Record<R>)
Это не работает, потому что Flow не поддерживает поддержку типов пересечений с объектами. Вот как это выглядит в действии.