2016-09-18 12 views
5

Chciałbym dodać Flow do mojego projektu javascript.Typy przepływów na obiektach

W kilku przypadkach robię coś takiego, mam obiekt.

const myObject = { 
    x: 12, 
    y: "Hello World" 
} 

Mam ogólną funkcję, która wykonuje pewne odwzorowanie na obiekcie, zachowując klucze, ale zastępując wartości.

function enfunctionate(someObject) { 
    return _.mapValues(myObject, (value) =>() => value) 
} 

Chciałbym funkcję powrotu typ {x:() => number, y:() => string} Czy istnieje sposób, aby to się stało?

Oczywiście, mógłbym wpisać go bardziej ogólnie jako {[key: string]: any}, ale straciłbym dużo statycznego pisania, który chciałbym uzyskać za pomocą przepływu.

Gdybym mógł zastąpić moje kilka przypadków, które robią to z generowaniem kodu lub makrami, które mogłyby działać, ale nie widzę dobrego sposobu, aby to zrobić z przepływem.

Czy istnieje sposób rozwiązania tego problemu?

+0

jako możesz zobaczyć tutaj https://docs.omniref.com/js/npm/lodash-node/3.1.0/symbols/_.mapValues ​​'mapValues' akceptuje' any' i zwraca ** kopię **, więc nie możesz zachować to w * typ *. – Hitmands

+0

Możliwy duplikat [Jak mogę wpisać funkcję z obiektami wejściowymi i wyjściowymi o tych samych kluczach, ale o różnych typach wartości?] (Http://stackoverflow.com/questions/35894181/how-do-i-type-a-function -with-input-and-output-objects-with-the-same-keys-but-di) –

Odpowiedz

4

To najlepsze co możesz dostać w momencie, gdy jest to bezpieczniejsze niż {[key: string]: any} tam wciąż any zaangażowany

function enfunctionate<O: Object>(someObject: O): { [key: $Keys<O>]: (...rest: Array<void>) => any } { 
    return _.mapValues(someObject, (value) =>() => value) 
} 

const obj = enfunctionate(myObject) 

obj.x() // ok 
obj.unknown() // error 

EDIT: począwszy od V.33 można użyć $ObjMap

function enfunctionate<O>(o: O): $ObjMap<O, <V>(v : V) =>() => V> { 
    return _.mapValues(o, (value) =>() => value) 
} 
+0

To nie jest doskonałe, ale jest o wiele lepsze niż to, co miałem, dzięki! –

+1

Właśnie dodano nową implementację (v0.33 +) – gcanti

+0

niesamowite! Jak się o tym dowiedziałeś? Czy gdzieś jest dokumentacja? –

0

Flow potrafi wnioskować o wielu rzeczach. Jeśli jednak chcesz przypiąć typy, musisz samemu utworzyć typy. Musisz utworzyć typ dla obiektu, który przekazujesz do enfunctionate, a następnie określić zwracany typ.

Możesz wpisać funkcję przy pomocy type alias. Możesz więc utworzyć nowy jawny typ dla tej funkcji.

function enfunctionate<X, Y>(x: X): Y { 
    return _.mapValues(myObject, (value) =>() => value) 
} 

Dopóki wiesz typ X, to wiesz, typ Y. Rodzaj aliasingu, generycznych i związki powinny być w stanie udzielić Ci elastyczność niezbędną.

Jednak myślę tak długo, jak długo typ mapValues jest określany dobrze (miejmy nadzieję, że przez kogoś innego), wtedy możesz uciec, po prostu określając typ, który przyjmuje enfunctionate i pozwala Flow wywnioskować typ zwrotu tej funkcji .

+0

Dzięki, ale tak naprawdę nie pomaga mi. Funkcje, które próbuję wpisywać, istnieją w celu wyeliminowania elementu standardowego, więc nie pomagają, jeśli muszę zdefiniować typy. Ponadto _.mapValues ​​napotyka na ten sam problem z pisaniem, co powoduje, że problem w rzeczywistości nie pomaga w niczym. –

Powiązane problemy