UNPKG

@tdi2/di-core

Version:

TypeScript Dependency Injection 2 - Core DI framework

55 lines (52 loc) 2.05 kB
import { JSX } from 'react'; /** * Marker interface for dependency injection in function parameters * Usage: function MyComponent(services: {logger: Inject<LoggerInterface>}) {} */ type Inject<T> = T & { readonly __inject__: unique symbol; }; /** * Marker type for optional dependency injection * Usage: function MyComponent(services: {logger?: InjectOptional<LoggerInterface>}) {} */ type InjectOptional<T> = T & { readonly __injectOptional__: unique symbol; }; /** * Service configuration for functional components * This would be detected by the transformer for functions with this parameter shape */ interface ServiceDependencies { [key: string]: Inject<any> | InjectOptional<any>; } /** * Utility type to extract the actual types from Inject markers */ type ExtractServices<T extends ServiceDependencies> = { [K in keyof T]: T[K] extends Inject<infer U> ? U : T[K] extends InjectOptional<infer U> ? U | undefined : never; }; /** * Function component with DI support * This is what the transformer would look for and transform */ interface DIFunction<TServices extends ServiceDependencies, TProps = object> { (props: TProps & { services?: ExtractServices<TServices>; }): JSX.Element; } /** * Helper type for creating DI-enabled function components * Example: * const MyComponent: DIComponent<{logger: Inject<LoggerInterface>}, {title: string}> = * ({title, services}) => { ... } */ type DIComponent<TServices extends ServiceDependencies, TProps = object> = DIFunction<TServices, TProps>; /** * Transform a regular React component to support DI * This could be used as a higher-order function or detected by the transformer */ declare function withDI<TServices extends ServiceDependencies, TProps = object>(component: (props: TProps & { services: ExtractServices<TServices>; }) => JSX.Element, serviceConfig: TServices): React.ComponentType<TProps>; export { type DIComponent, type DIFunction, type ExtractServices, type Inject, type InjectOptional, type ServiceDependencies, withDI };