Defining Type-Safe, Implementation-Agnostic Services in TypeScript

I feel like I've asked a similar question before, but what's the right way to define a service in a way that's agnostic to its implementation in terms of dependencies and potential errors? I have something like this:
class Lock extends Context.Tag("Lock")<
  Lock,
  {
    readonly acquireLock: <E, R>(key: string, timeoutSeconds: number) => Effect.Effect<void, E, R>,
    readonly releaseLock: <E, R>(key: string) => Effect.Effect<void, E, R>
  }
>() { }


But when I provide a service I get a type error like 'E' could be instantiated with an arbitrary type which could be unrelated to 'LockAcquisitionError | DatabaseError'.
Was this page helpful?