2016-09-18 1 views
5

Ich habe Flow zu meinem Javascript-Projekt hinzugefügt.Fließtypen für Objekte

In einigen Fällen mache ich so etwas, ich habe ein Objekt.

Und ich habe eine allgemeine Funktion, die einige Mapping auf das Objekt, die Keys aber die Werte zu ersetzen.

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

würde ich die Funktion wie die Art zurückkehren {x:() => number, y:() => string} Gibt es eine Möglichkeit, dies zu verwirklichen?

Natürlich könnte ich es generischer als schreiben, aber ich würde eine Menge der statischen Typisierung verlieren, die ich gerne mit dem Fluss gewinnen würde.

Wenn ich meine wenigen Fälle ersetzen könnte, die dies mit Code-Generierung oder Makros, die funktionieren könnten, aber ich sehe keinen guten Weg, das mit dem Fluss zu tun.

Gibt es eine Möglichkeit, dieses Problem zu lösen?

+0

Wie verwenden Sie können hier sehen https://docs.omniref.com/js/npm/lodash-node/3.1.0/symbols/_.mapValues ​​'mapValues' akzeptiert' any' und gibt eine ** Kopie ** zurück, die Sie nicht behalten können es in * typ *. – Hitmands

+0

Mögliches Duplikat von [Wie gebe ich eine Funktion mit Eingabe- und Ausgabeobjekten mit denselben Schlüsseln, aber unterschiedlichen Werttypen ein?] (Http://stackoverflow.com/questions/35894181/how-do-i-type-a-function) -mit-input-and-output-objects-with-the-same-keys-but-di) –

Antwort

4

Dies ist das Beste, was Sie im Moment bekommen, während es sicherer als {[key: string]: any} ist immer noch ein any

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 beteiligt gibt es: ab V.33 können Sie $ObjMap

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

Es ist nicht perfekt, aber es ist viel besser als das, was ich hatte, danke! –

+1

Gerade hinzugefügt eine neue Implementierung (v0.33 +) – gcanti

+0

genial! Wie hast du das herausgefunden? Gibt es irgendwo Dokumentation? –

0

Flow ist in der Lage, viele Dinge abzuleiten. Wenn Sie die Typen jedoch anheften möchten, müssen Sie die Typen selbst erstellen. Sie müssen einen Typ für das Objekt erstellen, das Sie an enfunctionate übergeben, und dann den Typ angeben, der zurückgegeben wird.

Sie können die Funktion mit type alias eingeben. Sie können also einen neuen expliziten Typ für diese Funktion erstellen.

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

Solange Sie die Art der X kennen, dann wissen Sie, welche Art von Y. Typ Aliasing, Generika und Gewerkschaften sollten Sie geben können Flexibilität, die Sie benötigen.

Allerdings bin ich auch so lange wie die Art der mapValues angegeben und (hoffentlich von jemand anderem) denken, dann können Sie weg mit nur den Typ angeben, dass enfunctionate nimmt und lassen Fluss den Rückgabetyp dieser Funktion schließen .

+0

Danke, aber hilft mir nicht wirklich. Die Funktionen, die ich versuche zu schreiben, gibt es, um den Textbaustein zu eliminieren, so dass sie nicht wirklich helfen, wenn ich die Typen definieren muss. Außerdem steht _.mapValues ​​dem gleichen Typisierungsproblem gegenüber, das heißt, das Problem zu lösen, hilft also nichts. –