TypeScript Inner Process Event Bus Example

Hey, I am currently trying to build an inner process event bus kind of thing and struggling with the types a bit.

Is there a way to describe all services (Context.Tag) which implement the same interface (here EventHandler<UserCreated>)?
import { Console, Context, Data, Effect, Layer, pipe } from 'effect';

type User = { id: number; name: string };

class EventHandlerError extends Data.TaggedError('EventHandlerError') {}

// events
interface DomainEvent {}

class UserCreated implements DomainEvent {
    constructor(public readonly user: User) {}
}

// handlers
interface EventHandler<T extends DomainEvent> {
    handle(domainEvent: T): Effect.Effect<void, EventHandlerError>;
}

class UserCreatedHandler1 implements EventHandler<UserCreated> {
    handle(domainEvent: UserCreated) {
        return Console.log(`[UserCreatedHandler1] received UserCreated event: ${domainEvent}`);
    }
}
class UserCreatedHandler1Context extends Context.Tag('UserCreatedHandler1Context')<
    UserCreatedHandler1Context,
    UserCreatedHandler1
>() {
    static readonly live = Layer.sync(UserCreatedHandler1Context, () => new UserCreatedHandler1());
}

class UserCreatedHandler2 implements EventHandler<UserCreated> {
    handle(domainEvent: UserCreated) {
        return Console.log(`[UserCreatedHandler2] received UserCreated event: ${domainEvent}`);
    }
}
class UserCreatedHandler2Context extends Context.Tag('UserCreatedHandler2Context')<
    UserCreatedHandler2Context,
    UserCreatedHandler2
>() {
    static readonly live = Layer.sync(UserCreatedHandler2Context, () => new UserCreatedHandler2());
}

const handler = [UserCreatedHandler1Context, UserCreatedHandler2Context];
Was this page helpful?