raveclassic/injectable-ts

injectableS. Struct way to solve same issue

coolassassin opened this issue · 1 comments

In fp-ts we have combine function and injectable work in a same way.
In my previous job I made a alternative function combineS, to work with Record of Readers instead of array.
I have mede a simple try to make something similar but with injectable.
What do you think?

type MapInjectablesStructToValues<Targets extends Record<string, unknown>> = {
  readonly [Index in keyof Targets]: InjectableValue<Targets[Index]>
}

type MergeStructDependencies<
  Inputs extends {[Key in keyof Inputs] :Injectable<UnknownDependencyTree, unknown>},
  Name extends PropertyKey | never,
  Type
> = {
  readonly name: Name
  readonly type: Type
  readonly optional: Name extends never ? false : true
  readonly children: InjectableDependencyTree<Inputs[keyof Inputs]>[]
}

export function injectableS<
  Name extends PropertyKey,
  Inputs extends {[Key in keyof Inputs] : (
    | Injectable<UnknownDependencyTree, unknown>
    | InjectableWithName<UnknownDependencyTree, unknown>
    )},
  Value
>(
  name: Name,
  inputs: Inputs,
  map: (values: MapInjectablesStructToValues<Inputs>) => Value
): InjectableWithName<
  {
    readonly [Key in keyof MergeStructDependencies<Inputs, Name, Value>]: MergeStructDependencies<Inputs, Name, Value>[Key]
  },
  Value
>

export function injectableS(
  ...args: readonly unknown[]
): Injectable<UnknownDependencyTree, unknown> {
  /// some code
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
  const t = (): any => {

  }
  return t
}

const bar = injectableS(123, {a: token('a')<'a'>()}, ({a}) => {
  return 1
})

const t = bar({a: 'a'})

Hey @coolassassin!

Thanks for the suggestion, indeed it would be handy in some cases. I've played a bit with the code and came up with a simple solution - check #16. Let's continue discussion there.