Закрытие компиляции набирает: обратитесь к функции (заводской метод)
Предположим, у меня есть класс с фабричным методом:
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
фабричный метод в другом классе, например:
/**
* @param {{
* createFoo: !function(!Object): !Foo
* }} options
*/
Проблема: Closure Compiler говорит, что это не соответствует формальному параметру.
found : {
createFoo: function ({a: number, b: number): Foo,
}
required: {
createFoo: function (Object): Foo,
}
Очевидно, я могу переписать подпись типа и жесткий код в записи, но я действительно хочу сослаться на Foo.create
поэтому нет необходимости обновлять всю кодовую базу каждый раз, когда я добавляю новый параметр в объект параметров.
Как я могу сделать это для CC?
2 ответа
Общая проблема заключается в том, что вам требуется функция, более приемлемая, чем метод Foo.create. Ник Сантос написал хорошее объяснение этого:
http://closuretools.blogspot.com/2012/06/subtyping-functions-without-poking-your.html
Использование свободной функции типа "Функция" или "! Функция" будет работать так, как вы надеетесь.
Я использовал это определение, чтобы проверить:
/** @param {{createFoo: !Function}} options */
function f(options) {}
f({createFoo: Foo.create});
Один из способов - написать тип один раз в 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
*/