#node.js #dependency-injection
#node.js #внедрение зависимостей
Вопрос:
Я рассматриваю возможность интеграции контейнера DI в один из моих существующих проектов nodejs. Я интегрировал awilix, и все работает так, как ожидалось.
Тем не менее, я привык к typescript и использую безопасность типов во многих частях. Это одна вещь, которую я не могу получить при регистрации зависимостей с помощью 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")
Приведенный выше код прекрасно работает при правильной конфигурации контейнера. Однако для разрешенного объекта функции нет вывода типа. Есть ли какой-нибудь способ получить типы?
Ответ №1:
Это не мой собственный оригинальный ответ, но я наткнулся на эту кодовую песочницу, которая может вам помочь: https://codesandbox.io/s/qykt1?file=/src/index.ts .
На случай, если ссылка исчезнет, вот фрагмент, извлеченный из приведенной выше ссылки.
Вся заслуга принадлежит автору, дерекрионесу (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;
}