castore icon indicating copy to clipboard operation
castore copied to clipboard

Provide eventType builder

Open Xample opened this issue 10 months ago • 0 comments

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')();

Xample avatar Mar 01 '25 15:03 Xample