
/*** makes all types in tuple readonly except functions
  * MakeReadonly<[object, Function, string[]]> is equal to
  * [ReadonlyObject<object>, Function, ReadonlyArray<string>]
 **/
type ReadonlyTuple<T> = {
  readonly [K in keyof T]: Immutable<T[K]>;
};
type Immutable<T> = T extends (infer P)[] ? ReadonlyArray<P> : T extends Map<infer TKey, infer TValue> ? ReadonlyMap<TKey, TValue> : T extends ReadonlyMap<any, any> ? T : T extends ReadonlyArray<any> ? T : T extends Function ? T : T extends object ? ReadonlyObject<T> : Readonly<T>;
export type ReadonlyObject<T> = {
  readonly [K in keyof T]: Immutable<T[K]>;
};
type TupleHead<T> = T extends [infer U, ...any[]] ? U : never;
export type PureComputed<TArgs extends any[], TReturn = TupleHead<TArgs>> = (...args: ReadonlyTuple<TArgs>) => Immutable<TReturn>;
export type GetMessageFn = (messageKey: string, params?: object) => string;

export interface IDependency {
  name: string;
  optional?: boolean;
}

