Skip to content

Instantly share code, notes, and snippets.

@tstelzer
Last active April 2, 2022 20:40
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tstelzer/90a5adf341d544e06f2231d498a1a441 to your computer and use it in GitHub Desktop.
Save tstelzer/90a5adf341d544e06f2231d498a1a441 to your computer and use it in GitHub Desktop.
import * as T from '@effect-ts/core/Effect';
import * as Has from '@effect-ts/core/Has';
type T = (a: any) => (b: any) => T.UIO<void>;
export const tag = Has.tag<{foo: T}>(Symbol('foo'));
export type ShapeFn2<T> = Pick<
T,
{
[k in keyof T]: T[k] extends (
...args1: infer ARGS1
) => (...args2: infer ARGS2) => T.Effect<infer R, infer E, infer A>
? ((
...args1: ARGS1
) => (...args2: ARGS2) => T.Effect<R, E, A>) extends T[k]
? k
: never
: never;
}[keyof T]
>;
export type DerivedLifted<T, Fns extends keyof ShapeFn2<T>> = {
[k in Fns]: T[k] extends (
...args1: infer ARGS1
) => (...args2: infer ARGS2) => T.Effect<infer R, infer E, infer A>
? (
...args1: ARGS1
) => (...args2: ARGS2) => T.Effect<R & Has.Has<T>, E, A>
: never;
};
export function deriveLifted2n<T>(
H: Has.Tag<T>,
): <Fns extends keyof Shape2n<T> = never>(
functions: Fns[],
) => DeriveLifted2n<T, Fns> {
return functions => {
const ret = {} as any;
for (const k of functions) {
ret[k] =
(...args1: any[]) =>
(...args2: any[]) =>
T.accessServiceM(H)(h => (h[k] as any)(...args1)(...args2));
}
return ret as any;
};
}
export const {foo} = deriveLifted(tag)(['foo']);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment