diff --git a/packages/microservices/decorators/event-pattern.decorator.ts b/packages/microservices/decorators/event-pattern.decorator.ts index f4973d741bf..60c2e862d3d 100644 --- a/packages/microservices/decorators/event-pattern.decorator.ts +++ b/packages/microservices/decorators/event-pattern.decorator.ts @@ -13,12 +13,39 @@ import { import { Transport } from '../enums'; import { PatternHandler } from '../enums/pattern-handler.enum'; +export type EventDataMethodDecorator< + TEventTypes extends Record, + TKey extends keyof TEventTypes, +> = ( + target: object, + propertyKey: string | symbol, + descriptor: TypedPropertyDescriptor< + (data: TEventTypes[TKey], ...args: unknown[]) => any + >, +) => void; + /** * Subscribes to incoming events which fulfils chosen pattern. * * @publicApi */ export const EventPattern: { + >( + topic: keyof TEventTypes, + ): EventDataMethodDecorator; + >( + topic: keyof TEventTypes, + transport: Transport | symbol, + ): EventDataMethodDecorator; + >( + topic: keyof TEventTypes, + extras: Record, + ): EventDataMethodDecorator; + >( + topic: keyof TEventTypes, + transport: Transport | symbol, + extras: Record, + ): EventDataMethodDecorator; (metadata?: T): MethodDecorator; (metadata?: T, transport?: Transport | symbol): MethodDecorator; (metadata?: T, extras?: Record): MethodDecorator; diff --git a/packages/microservices/test/decorators/event-pattern.decorator.spec.ts b/packages/microservices/test/decorators/event-pattern.decorator.spec.ts index 13cbb268441..6a951e35d18 100644 --- a/packages/microservices/test/decorators/event-pattern.decorator.spec.ts +++ b/packages/microservices/test/decorators/event-pattern.decorator.spec.ts @@ -85,6 +85,28 @@ describe('@EventPattern', () => { public static test() {} } + type TestComponent6EventTypes = { + 'event-pattern-foo': { foo: string }; + 'event-pattern-bar': { bar: number }; + }; + + // Static tests exclusively for type safety: + class TypeTestComponent { + @EventPattern('event-pattern-foo') + testFoo(_event: { foo: string }, _additionalArg: string) {} + + @EventPattern('event-pattern-bar') + testBar(_event: { bar: number }) {} + + // @ts-expect-error -- `foo` should be a string, not a number + @EventPattern('event-pattern-foo') + testFooMismatch(_event: { foo: number }) {} + + // @ts-expect-error -- `_event` should be `{ foo: string; }`, not a string + @EventPattern('event-pattern-foo') + testFooMismatch2(_event: string) {} + } + it(`should enhance method with ${PATTERN_METADATA} metadata`, () => { const [metadataArg] = Reflect.getMetadata( PATTERN_METADATA,