2016-03-31 11 views
4

Предположим, у меня есть класс с фабричным методом:Закрытие компилятор типирование: Обратитесь к функции (метод фабрики)

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); 
    } 
} 

Я хочу зависимостей впрыснуть Foo «s фабричный метод в другом классе, как:

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

Проблема: Closure Compiler говорит, что это не соответствует формальному параметру.

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

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

Очевидно, что я могу переписать тип подписи и жесткий код в записи, но я действительно хочу обратиться к Foo.create так что нет никакой необходимости обновления всего CodeBase каждый раз, когда я добавить новый параметров объекта варианты.

Как я могу это сделать для CC?

ответ

2

Общая проблема заключается в том, что вы требуете функции, которая более терпимым, чем метод Foo.create. Ник Сантос написал хорошее объяснение этого:

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

Использование рыхлую функции типа «Function» или «! Функция» будет работать, как вы хотели бы надеяться.

Я использовал это определение для проверки:

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

f({createFoo: Foo.create}); 

CC debugger sample

3

Один из способов - написать тип один раз в typedef, а затем обратиться к нему в обоих местах. (Я не пробовал это, но я думаю, что он должен работать)

/** @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

Или используйте '@ record' –