opinionated-machine
Version:
Very opinionated DI framework for fastify, built on top of awilix
44 lines • 1.54 kB
JavaScript
/**
* Create type-safe guard functions for a discriminated union metadata type.
*
* Returns an object mapping each discriminant value to a type guard function.
* When a guard returns true, TypeScript narrows the metadata to the specific
* variant, giving access to variant-specific fields.
*
* The double-invocation `defineEventMetadata<Type>()(field, values)` is needed
* because TypeScript doesn't support partial type inference.
*
* @template TMetadata - The full discriminated union type
*
* @example
* ```typescript
* type EventMetadata =
* | { scope: 'project'; projectId: string }
* | { scope: 'team'; teamId: string }
* | { scope: 'global' }
*
* const metadata = defineEventMetadata<EventMetadata>()('scope', [
* 'project',
* 'team',
* 'global',
* ])
*
* if (metadata.project(event.metadata)) {
* // TypeScript narrows: event.metadata is { scope: 'project'; projectId: string }
* event.metadata.projectId // string
* }
* ```
*/
export function defineEventMetadata() {
return (field, values) => {
const guards = {};
for (const value of values) {
// Index by the raw value so numeric and string discriminants stay distinct
// (e.g. `1` and `'1'` produce separate keys). Still safe under JS coercion
// because the `metadata[field] === value` check inside the guard uses ===.
guards[value] = (metadata) => metadata[field] === value;
}
return guards;
};
}
//# sourceMappingURL=defineEventMetadata.js.map