2016-03-31 9 views
4

Angenommen, ich eine Klasse mit einer Factory-Methode haben:Closure Compiler Typisierung: Siehe Funktion (Factory-Methode)

export class Foo { 
    constructor(options) { 
     this.a = options.a; 
     this.b = options.b; 
    } 

    /** 
    * @param {{ 
    * a: number, 
    * b: number 
    * }} options 
    * @return {!Foo} 
    */ 
    static create(options) { 
     return new Foo(options); 
    } 
} 

Ich will Foo ‚s Factory-Methode in einer anderen Klasse der Abhängigkeits zu injizieren, wie:

/** 
* @param {{ 
* createFoo: !function(!Object): !Foo 
* }} options 
*/ 

Das Problem: Closure Compiler sagt, dies stimmt nicht mit dem formalen Parameter überein.

found : { 
    createFoo: function ({a: number, b: number): Foo, 
} 

required: { 
    createFoo: function (Object): Foo, 
} 

Natürlich kann ich die Art Signatur und harten Code in der Aufzeichnung neu zu schreiben, aber ich mag wirklich Foo.create so beziehen gibt es keine Notwendigkeit, die gesamte Codebasis mir einen neuen param jedes Mal zu aktualisieren, hinzuzufügen, um die Optionen zu widersprechen.

Wie kann ich das für CC tun?

Antwort

2

Das allgemeine Problem ist, dass Sie eine Funktion benötigen, die mehr zu akzeptieren als die Foo.create Methode. Nick Santos eine gute Erklärung dafür schrieb:

http://closuretools.blogspot.com/2012/06/subtyping-functions-without-poking-your.html

einen losen Funktionstypen „Funktion“ oder „! Funktion“ wird Verwenden arbeiten, wie Sie es wünschen.

benutzte ich diese Definition zu überprüfen:

/** @param {{createFoo: !Function}} options */ 
function f(options) {} 

f({createFoo: Foo.create}); 

CC debugger sample

3

Eine Möglichkeit besteht darin, den Typ einmal in einem typedef zu schreiben und dann an beiden Stellen darauf zu verweisen. (Ich habe nicht versucht, aber ich denke, es sollte funktionieren)

/** @typedef {function({a: number, b:number}): Foo} */ 
var FooCreator; 

export class Foo { 
    ... 

    /** 
    * @type {FooCreator} 
    */ 
    static create(options) { 
     return new Foo(options); 
    } 
} 

/** 
* @param {{ 
* createFoo: FooCreator 
* }} options 
*/ 
+0

Oder verwenden '@ Record' –

Verwandte Themen