I have some extremely repetative code in TypeScript where I need to do essentially this dozens and dozens of times:
const IdPIdChangedDecoder = D.struct({
newIdpId: UuidDecoder,
})
export type IdPIdChangedPayload = D.TypeOf<typeof IdPIdChangedDecoder>;
export const IdPIdChanged: EventMeta<Customer, IdPIdChangedPayload> = {
name: EventNames.IdPIdChanged,
decoder: IdPIdChangedDecoder,
fn: (customer, p) => {
return { ...customer, idpId: p.payload.newIdpId, lastUpdated: p.timestamp }
},
}
export type IdPIdChanged = KnownEvent<EventNames.IdPIdChanged, EmailAddressChangedPayload>
As is evident the IdpIdChanged
is repeated no less than 9 times in a single block.
Coming from Rust, I'd probably reach for a Macro in this scenario, because given a name, and a decoder, I could simply metaprogram that out.
In all my research however it seems like TypeScript compilers don't support anything like this in general?
Is there any general option to reduce the boilerplate? Bonus points if I can also eliminate the EventNames.IdpIdChanged
enum (enum Eg { IdpIdChanged = "idp_id_changed" , }
), and also add all the KnownEvent
variants to a union type.
This is all boilerplate for an event driven system I am working on, and the various flavors of events, decoders, types, constants and such are all used in either the read, or write- side of the system, someplace or other.
I would have some limited flexibility in changing these types for a different paradigm, but not a great deal.