type Prettify<T> = { [K in keyof T]: T[K] } & {};
type UserEvent = { user: { id: string } };
type EventHandler<Context> = (
event: UserEvent,
ctx: Context,
) => Promise<unknown>;
const init = {};
interface UserEventHandlers<
Context extends { [key: string]: unknown } = typeof init,
Handlers extends { [key: string]: EventHandler<unknown[]> } = typeof init,
> {
setContext<const Key extends string, Value>(): UserEventHandlers<
Prettify<Record<Key, Value> & Context>,
Handlers
>;
addStrategy<const Type extends string>(
key: Type,
handler: EventHandler<Context>,
): UserEventHandlers<
Context,
Prettify<Handlers & Record<Type, EventHandler<Context>>>
>;
run<T extends keyof Handlers>(
context: Context,
key: T,
event: UserEvent,
): Promise<void>;
}
declare const bareEventHandlers: UserEventHandlers;
const userEventHandlers = bareEventHandlers
.setContext<"kick", (id: string) => Promise<unknown>>()
.setContext<"ban", (id: string) => Promise<unknown>>()
.addStrategy("kick", async ({ user }, { kick }) => kick(user.id))
.addStrategy("ban", async ({ user }, { ban }) => ban(user.id));
const ctx = { kick: async () => {}, ban: async () => {} };
userEventHandlers.run(ctx, "kick", { user: { id: "123" } });
userEventHandlers.run(ctx, "ban", { user: { id: "123" } });
type Prettify<T> = { [K in keyof T]: T[K] } & {};
type UserEvent = { user: { id: string } };
type EventHandler<Context> = (
event: UserEvent,
ctx: Context,
) => Promise<unknown>;
const init = {};
interface UserEventHandlers<
Context extends { [key: string]: unknown } = typeof init,
Handlers extends { [key: string]: EventHandler<unknown[]> } = typeof init,
> {
setContext<const Key extends string, Value>(): UserEventHandlers<
Prettify<Record<Key, Value> & Context>,
Handlers
>;
addStrategy<const Type extends string>(
key: Type,
handler: EventHandler<Context>,
): UserEventHandlers<
Context,
Prettify<Handlers & Record<Type, EventHandler<Context>>>
>;
run<T extends keyof Handlers>(
context: Context,
key: T,
event: UserEvent,
): Promise<void>;
}
declare const bareEventHandlers: UserEventHandlers;
const userEventHandlers = bareEventHandlers
.setContext<"kick", (id: string) => Promise<unknown>>()
.setContext<"ban", (id: string) => Promise<unknown>>()
.addStrategy("kick", async ({ user }, { kick }) => kick(user.id))
.addStrategy("ban", async ({ user }, { ban }) => ban(user.id));
const ctx = { kick: async () => {}, ban: async () => {} };
userEventHandlers.run(ctx, "kick", { user: { id: "123" } });
userEventHandlers.run(ctx, "ban", { user: { id: "123" } });