Creating a TypeScript service with generics can indeed be tricky, especially when dealing with co...

Hello, I'm trying to create a service that has a generic and wonder whether there would be a more elegant way than what I currently have:

import { Config, Context, Effect, Layer } from "effect";

interface IPersistenceModel {  _id: string; }

const makeDefault = <PTX extends IPersistenceModel = IPersistenceModel>() =>
  Effect.gen(function* () {
    // simplified service for brevity
    const someValue = yield* Config.string("FOO");
    return {
      get: () =>
        Effect.gen(function* () {
          return { _id: "foo" } as PTX;
        }),
    };
  });

interface Repository<PTX extends IPersistenceModel>
  extends Effect.Effect.Success<ReturnType<typeof makeDefault<PTX>>> {}

const Repository = <PTX extends IPersistenceModel>() =>
  Context.GenericTag<Repository<PTX>>("Repository");

const RepositoryLayer = <PTX extends IPersistenceModel>() =>
  Layer.effect(Repository<PTX>(), makeDefault<PTX>());

// usage example
interface Foobar extends IPersistenceModel {
  name: string;
}

const program = Effect.gen(function* () {
  const repo = yield* Repository<Foobar>();
  const a = yield* repo.get(); // gets inferred as Foobar
});


I define my other services by extending Context.Tag, but haven't found a way to pass the generic through..
Was this page helpful?