问题描述
我正在考虑将DI容器集成到我现有的nodejs项目之一中。我已经集成了awilix,并且一切正常。
但是,我习惯于在许多地方使用打字稿并使用打字安全性。使用awilix注册依赖项是我无法做到的。
例如我写了高阶函数之类的用例
function createReport(specs){
const {reportRepostiory} = specs;
return async (param1: string,param2: string){
//...
reportRepostiory.create({//some payload})
}
}
const reportService : any = container.resolve("createReport");
const result = await reportService("1","2")
以上代码在正确的容器配置下可以正常工作。但是,在解析的函数对象上没有类型推断。有没有办法获取类型?
解决方法
这不是我自己的原始答案,但我遇到了这个可能对您有帮助的代码沙箱:https://codesandbox.io/s/qykt1?file=/src/index.ts。
如果链接失效,这里是从上述链接中提取的片段。
所有功劳归功于作者 derekrjones (https://codesandbox.io/u/derekrjones)。
import {
AwilixContainer,asFunction,asValue,asClass,InjectionMode,createContainer,Resolver,ResolveOptions,ContainerOptions
} from "awilix";
/**
* Container definition base.
*/
interface ContainerDefinition {
[key: string]: Resolver<unknown>;
}
/**
* Extracts the type that will be resolved from a resolver.
*/
type ExtractResolverType<T> = T extends Resolver<infer X> ? X : null;
/**
* Strongly-typed container.
*/
interface TypedAwilixContainer<T extends ContainerDefinition>
extends Pick<AwilixContainer,Exclude<keyof AwilixContainer,"resolve">> {
/**
* Resolves the registration with the given name.
*
* @param {string} name
* The name of the registration to resolve.
*
* @return {*}
* Whatever was resolved.
*/
resolve<K extends keyof T>(
key: K,resolveOptions?: ResolveOptions
): ExtractResolverType<T[K]>;
}
/**
* Wraps `createContainer` and calls `register` on it.
*/
function createTypedContainer<T extends ContainerDefinition>(
registrations: T,opts?: ContainerOptions
): TypedAwilixContainer<T> {
return createContainer(opts).register(registrations) as any;
}