40 votes

Comment décrire une forme de carte Immutable.js avec Flow

Je voudrais décrire la forme d'une carte en utilisant les définitions de type de flux d'Immutable.

Vous pouvez décrire la forme d'un objet par :

const stateShape: {
  id: number,
  isActive: boolean
} = {
  id: 123,
  isActive: true
};

Y a-t-il quelque chose de similaire pour les cartes d'Immutable ?

30voto

Kriegslustig Points 2033

TL;DR ;

Non, mais en utilisant Records, vous pouvez faire en sorte que Flow vérifie la forme mais pas les types.

Longform

Le site correct la réponse serait : non, puisque les cartes n'ont pas de formes (au moins dans Flow et Immutable) . Mais Immuable a un type pour "Cartes" avec des formes. Ce serait Enregistrements . Mais pour des raisons décrites ci-dessous (puisque ce n'est pas strictement pertinent), la libdef de flux pour Immutable.Record est très lâche et ne vérifie pas les formes.

Une meilleure libdef d'enregistrement

Si nous ignorons la fonctionnalité (sans doute inutile) d'accès direct aux propriétés des enregistrements, nous pouvons créer une meilleure libdef. Elle ressemblerait à ceci :

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

Avec cette déclaration, nous pouvons définir la forme de l'enregistrement. . Le voici en action . Mais nous ne pouvons toujours pas définir les types des valeurs réelles. Flow définit un type non documenté $PropertyType<T, K> type. Qui prend un objet T et une chaîne littérale K . Pour faire $PropertyType dans notre cas, il faudrait qu'elle fonctionne pour $Keys<T> qui est un type d'union de chaînes de caractères. Il y a quelques semaines, une question a été ouverte pour que cela se produise. Il peut être trouvé ici .

Différence entre carte et objet

En termes de flux, ils sont assez différents. C'est une carte :

type MyMaps = { [key: string]: number }

Les clés réelles sont inconnues. La seule chose que Flow sait, c'est que toutes les clés doivent être des chaînes de caractères et que toutes les valeurs doivent être des nombres. D'un autre côté, un type d'objet ressemble à quelque chose comme :

type MyObject = { a: string, x: boolean }

Lors de la création ou de la modification d'un objet, newObj de type MyObject Flow, va vérifier que newObj.a est une chaîne de caractères et newObj.x est un booléen.

Pourquoi la définition actuelle est si vague

Un enregistrement expose chaque paire clé/valeur par un accès direct aux clés.

type R = { a: string }
const r = Record({ a: 'Supa' })
r.a === r.get('a')

Cela nécessiterait la définition du type de r pour être une intersection de Record<R> y R (pas exactement, mais c'est assez proche). Donc :

(r: R & Record<R>)

Cela ne fonctionne pas car Flow ne prend pas en charge les types d'intersection avec les objets. Voici à quoi cela ressemble en action .

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X