castore
castore copied to clipboard
Provide eventType builder
I'm always frustrated when I've to denormalize something in my code for instance:
import { EventType } from '@castore/core';
const pokemonAppearedEventType = new EventType<
'POKEMON_APPEARED',
{ name: string; level: number },
{ trigger?: 'random' | 'scripted' }
>({ type: 'POKEMON_APPEARED' });
We are writing POKEMON_APPEARED twice.
Describe the solution you'd like This simple builder:
const createEventTypeBuilder = <T extends string>(type: T) => {
return <Payload, Metadata = undefined>() =>
new EventType<T, Payload, Metadata>({ type });
};
const pokemonAppearedEventType = new createEventTypeBuilder('POKEMON_APPEARED')<{ name: string; level: number }, { trigger?: 'random' | 'scripted' }>();
Describe alternatives you've considered Slightly more advanced but also possible:
const createEventTypeBuilder = <T extends string>(type: T) => {
return <Config extends { Payload?: unknown; Metadata?: unknown } = {}>() =>
new EventType<
T,
Config extends { Payload: infer P } ? P : string extends T ? unknown : never,
Config extends { Metadata: infer M } ? M : string extends T ? unknown : never
>({ type });
};
// Payload + Metadata
const pokemonAppearedEventType = createEventTypeBuilder('POKEMON_APPEARED')<
{ Payload: { name: string; level: number }; Metadata: { trigger?: 'random' | 'scripted' } }
>();
// Only Payload
const eventWithOnlyPayload = createEventTypeBuilder('ONLY_PAYLOAD')<
{ Payload: { value: number } }
>();
// Only Metadata
const eventWithOnlyMetadata = createEventTypeBuilder('ONLY_METADATA')<
{ Metadata: { source: string } }
>();
// Empty event
const eventWithoutPayloadOrMetadata = createEventTypeBuilder('EMPTY')();