web-dev-qa-db-fra.com

Flux: créez un type de flux en étendant un autre type

type someType = {
  keyOne: string,
  keyTwo: string,
};

type someOtherType = {
  keyOne: string,
  keyTwo: string,
  keyThree: string,
};

Ces deux types sont des objets qui contiennent keyOne et keyTwo, la seule différence est le dernier étend l'ancien avec une clé supplémentaire de keyThree.

Plutôt que d'écrire du code dupliqué, est-il possible de construire le type de flux someOtherType en étendant someType? Dans mon esprit, le repos/propagation d'objet ES6 me vient à l'esprit, mais je ne sais pas comment accomplir quelque chose comme ça dans Flow.

Merci!

20
Jon Cursi

Ce que vous recherchez est le type d'intersection . Selon la documentation:

Un type d'intersection nécessite qu'une valeur soit tous les types d'entrée.

Syntaxe: Intersection: <type 1> & <type 2> ... & <type n>

Le type d'intersection est destiné à étendre un type existant et à lui ajouter des exigences de type supplémentaires.

type someType = {
  keyOne: string,
  keyTwo: string
}

type someOtherType = someType & {
  keyThree: string
}

const shouldBeOk: someOtherType = {
  keyOne: 'biz',
  keyTwo: 'buzz',
  keyThree: 'baz',
}

const shouldError: someOtherType = {
  keyOne: 123,
  keyTwo: 'hello',
  keyThree: 'world',
}

// flow error:
16: const shouldError: someOtherType = {
                               ^ object literal. This type is incompatible with
8: type someOtherType = someType & {
                        ^ object type

L'opposé logique du type d'intersection est le type d'union . Selon la documentation:

Un type d'union requiert qu'une valeur soit l'un des types d'entrée.

Syntaxe: Union: <type 1> | <type 2> ... | <type n>

Par exemple. vous pouvez utiliser le type d'union pour créer un énumérable.

type fooBarBazType = 'foo' | 'bar' | 'baz';
const shouldBeOk: fooBarBazType = 'bar';

const shouldError: fooBarBazType = 'buzz';

4: const shouldError: fooBarBazType = 'buzz';
                                      ^ string. This type is incompatible with
4: const shouldError: fooBarBazType = 'buzz';
                      ^ string enum
25
thejohnbackes

Désolé, la réponse acceptée est tout simplement fausse et cela fonctionne simplement parce que vous n'avez pas utilisé la correspondance exacte.

Lorsque vous utilisez la correspondance exacte, vous obtiendrez une erreur :

10: const shouldBeOk: someOtherType = {
^ Impossible d'affecter le littéral d'objet à shouldBeOk car la propriété keyOne est manquante dans le type d'objet 1 mais existe dans le littéral d'objet 2 =. Références: 6: tapez someOtherType = someType & {|
^ 1 10: const shouldBeOk: someOtherType = {
^ 2

La bonne façon de le faire est d'utiliser l'opération spread:

type someOtherType = {|
  ...someType,
  keyThree: string
|}

démo

2
shem