2017-02-13 17 views
11

Say mam następujący stały ciąg:rodzaje przepływów z ciągami stałymi oraz typy zależne

export default const FOO = 'FOO'

powiedzieć, że import ten w adnotacją pliku przepływu tak:

import FOO from '../consts/Foo'

Następnie mam funkcję:

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

nie typecheck z:

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 

Więc moje pytania to:

1) możliwe jest używać stałych typów przepływu, jak mogę odtworzyć to zachowanie?

2) Czy możliwe jest wykonywanie zależnych typów w przepływie? więc na przykład, czy mogę kodować, poprzez typy, że zwracany ciąg musi być tym samym ciągiem, który jest przekazywany do funkcji example?

EDIT: Wyjaśnienie do części 2: Czy jest możliwe, aby w jakiś sposób wskazać, że parametr foo przekazywane do funkcji example jest w rzeczywistości ten sam ciąg jako ciąg w kluczu obiektu powrotnej foo? Lub twierdzić, że wejście i wyjście mają tę samą długość (na przykład funkcja szyfru przesunięcia). Lub powiedzmy, że zawiera permutację tych samych znaków? (dla shuffle).

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

+0

Jeśli chcesz, aby 'FOO' miał typ' 'FOO'', musisz go zadeklarować, w przeciwnym razie jest to tylko ciąg znaków. W przypadku obiektów, należy wtedy wpisać 'type: typeof FOO', jak mówi błąd. Nie jestem do końca pewien, o co pytasz w swoim 2) punkcie. Wówczas otrzymasz obiekt z dwiema właściwościami o tej samej wartości ciągu. – loganfsmyth

Odpowiedz

5

Zamiast deklarowania FOO jako const, zadeklarować ją jako suma rozłączna z jednego oddziału:

type FOO = "FOO" 

Następnie kod może być aktualizowana tak:

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

Jeśli używasz dowolnej wartości oprócz dokładnego ciągu literowego "FOO", gdzie FOO jest wymagane, to jest błąd kompilacji.

Jeśli wolisz zachować stałą wartość, będziesz musiał nazwać ten typ inaczej, ponieważ mogą się zderzyć. Więc można zrobić:

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

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

Niestety, nie widzę sposobu, aby uniknąć powielania ciąg dosłowne, ponieważ typ rozłączne składnia definicji unia dopuszcza tylko literały i typy, a nie zmienne, nawet jeśli są one stałe.

+0

dla standardowego wzorca akcji Flux definiującego typy działań jako łańcuchy, aby usunąć niektóre z cytatów z kodu, jest to bardzo interesujący wzorzec. W ten sposób i popraw mnie, jeśli się mylę, mogę zdefiniować typ meta 'ValidResponses = FOO | BAR; 'i upewnij się, że wywołanie funkcji API zwraca poprawną odpowiedź, a nie tylko poprawny typ danych. – ermik