我正在使用Inverseify v4.13.0和Typescript,这两个都是我的新手。
我有一个Logger
界面:
interface Logger {
log(level: string, message: string, meta?: any): void;
}
一个TYPES文件:
const TYPES = {
Config: Symbol.for('Config'),
LoggerFactory: Symbol.for('Factory<Logger>')
};
和一些绑定,包括我有问题的记录器工厂绑定,该绑定也将config对象作为参数:
referenceContainer.bind<Config>(TYPES.Config).to(Config);
referenceContainer.bind<interfaces.Factory<Logger>>(TYPES.LoggerFactory).toFactory<Logger>(
(context: interfaces.Context) => {
return (options: PrefixedLoggerOptions = {}): Logger => {
// return an object that implements Logger
return PrefixedLoggerFactory(options);
};
});
然后我尝试使用记录器:
async function runApp() {
const config = referenceContainer.get<Config>(TYPES.Config);
const logger = referenceContainer.get<interfaces.Factory<Logger>>(TYPES.LoggerFactory)(config.loggerOptions);
// **** error: logger has no 'log' property ****
logger.log('info', 'am I a logger? nope!');
// but this works
(logger as Logger).log('info', 'am I a logger? yep!');
}
(async () => {
await runApp();
})();
如果我尝试使用Logger而不进行投射,则会看到此错误:
error TS2339: Property 'log' does not exist on type 'Logger | ((...args: any[]) => Logger)'.
Property 'log' does not exist on type '(...args: any[]) => Logger'.
工厂似乎正在返回其自身的联合返回类型-工厂函数(奇怪的??)和记录器。
我检查了typedef,尽管我不知道如何工作,但这似乎是正确的。来自typedef:
type Factory<T> = (...args: any[]) => (((...args: any[]) => T) | T);
我对工厂使用inverseify错误吗?我该如何纠正?
答案 0 :(得分:0)
我正在猜测为什么要以这种方式实现-允许在绑定时进行两次迭代。如果Factory不是联合类型,则将无法绑定以下内容:
context => (options) => (destination) => { ...destination based logger... }
但是,正如您刚刚指出的,如果您确定工厂不会返回闭包,则可以将其转换为所需的类型。您也可以在分配时做到这一点:
const logger: Logger = referenceContainer.get<interfaces.Factory<Logger>>(TYPES.LoggerFactory)(config.loggerOptions) as Logger;
此外,最好使用@inject
装饰器。我认为,由于这是runApp
函数,就像一个入口点,因此可以使用它。但是否则,为了获得良好的去耦和可测试性,我们应该使用装饰器。