2017-02-13 2 views
11

Dire que j'ai la chaîne constante suivante:types de flux avec chaînes constantes et types dépendants

export default const FOO = 'FOO'

dire que j'importer ceci dans un fichier annoté de flux comme ceci:

import FOO from '../consts/Foo'

J'ai alors une fonction:

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

Cela ne Typecheck pas:

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 

Mes questions sont les suivantes:

1) est-il possible d'utiliser des constantes dans les types de flux, comment puis-je reproduire ce comportement?

2) Est-il possible de faire des types dépendants dans le flux? Ainsi, par exemple, pourrais-je encoder, à travers les types, que la chaîne qui est retournée doit être la même que celle qui est passée dans la fonction example?

EDIT: clarification à la partie 2: Est-il possible de d'une certaine façon d'indiquer que le paramètre foo passé dans la fonction example est en fait la même chaîne que la chaîne à la clé foo dans l'objet de retour? Ou pour affirmer que l'entrée et la sortie ont la même longueur (par exemple une fonction de chiffrement par décalage). Ou dire contenir une permutation des mêmes caractères? (pour un shuffle).

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

+0

Si vous voulez que FOO ait le type FOO, vous devez le déclarer, sinon c'est juste une chaîne. Pour les objets, vous devez alors faire 'type: typeof FOO' comme l'indique l'erreur. Je ne suis pas tout à fait sûr de ce que vous demandez à votre 2 point cependant. Ensuite, vous finiriez avec un objet avec deux propriétés avec la même valeur de chaîne. – loganfsmyth

Répondre

5

Au lieu de déclarer FOO comme const, déclarer comme une union disjointe avec juste une branche:

type FOO = "FOO" 

Ensuite, votre code peut être mis à jour comme celui-ci:

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

Si vous utilisez une valeur autre que la chaîne littérale exacte "FOO"FOO est requis, alors il s'agit d'une erreur de compilation.

Si vous préférez conserver votre constante, vous devrez nommer le type différemment, car ils entreraient en collision. Ainsi, vous pouvez faire:

const FOO = "FOO" 
type FooType = "FOO"; 

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

Malheureusement, je ne vois pas un moyen d'éviter de dupliquer la chaîne littérale, car le type de syntaxe de définition disjointe permet seulement littéraux et types, pas les variables même si elles sont constantes.

+0

pour le modèle d'action standard Flux de définir des types d'action en tant que chaînes pour effacer certaines des citations du code, c'est un modèle très intéressant. De cette façon, et corrigez-moi si je me trompe, je peux définir un type de méta 'ValidResponses = FOO | BAR; 'et assurez-vous que l'appel de la fonction API renvoie une réponse correcte, pas seulement un type de données correct. – ermik