Skip to content
Typescript support for moleculer service actions and events
TypeScript JavaScript
Branch: master
Clone or download
Latest commit 1dec031 Jan 15, 2020
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
src Initial commit of moleculer-service-ts Jan 4, 2020
test Admitting defeat to stupid tools out there that don't natively suppor… Jan 15, 2020
.eslintrc.js
.gitignore Initial commit of moleculer-service-ts Jan 4, 2020
.prettierrc Initial commit of moleculer-service-ts Jan 4, 2020
LICENSE Initial commit Jan 3, 2020
README.md Removed some eslint disable tags from README code snippets. Jan 4, 2020
image1.png Updated README Jan 4, 2020
image2.png Updated README Jan 4, 2020
image3.png Updated README Jan 4, 2020
package-lock.json 1.0.2 Jan 15, 2020
package.json 1.0.2 Jan 15, 2020
tsconfig.json Admitting defeat to stupid tools out there that don't natively suppor… Jan 15, 2020

README.md

moleculer-service-ts

Typescript support for moleculer service actions and events

Installation

npm install moleculer-service-ts

Use

Define actions you handle and events you emit in your service in a <service>.service.types.ts file:

Example sample1.service.types.ts:

import {
  GenericActionWithParameters,
  GenericActionWithoutParameters,
  GenericEventWithoutPayload,
  GenericEventWithPayload
} from 'moleculer-service-ts';

export type ServiceName = 'sample1';

export type ServiceAction =
  | GenericActionWithoutParameters<'sample1.hello', string>
  | GenericActionWithParameters<
      'sample1.boo',
      { foo: string; bar?: string },
      string
    >
  | GenericActionWithParameters<
      'sample1.welcome',
      { name: string },
      string
    >;

export type ServiceEvent =
  | GenericEventWithoutPayload<'sample1.event1'>
  | GenericEventWithPayload<'sample1.event2', { id: string }>;

Example sample2.service.types.ts:

import {
  GenericActionWithParameters,
  GenericActionWithoutParameters,
  GenericEventWithoutPayload,
  GenericEventWithPayload
} from 'moleculer-service-ts';

export type ServiceName = 'sample2';

export type ServiceAction =
  | GenericActionWithoutParameters<'sample2.hello', string>
  | GenericActionWithParameters<
      'sample2.boo',
      { foo: string; bar?: string },
      string
    >
  | GenericActionWithParameters<
      'sample2.welcome',
      { name: string },
      string
    >;

export type ServiceEvent =
  | GenericEventWithoutPayload<'sample2.event1'>
  | GenericEventWithPayload<'sample2.event2', { id: string }>;

Then, when you want to call actions and emit events, you import the type definitions and feed them to a typed moleculer broker from this package:

main.ts:

import { TypedServiceBroker } from 'moleculer-service-ts';

// import the service types from sample1 service
import {
  ServiceAction as Sample1Action,
  ServiceEvent as Sample1Event,
  ServiceName as Sample1Name
} from './sample1.service.types'; // eslint-disable-line import/extensions

// import the actual service schema of the sample1 service
import sample1 from './sample1.service'; // eslint-disable-line import/extensions

// import the service types from sample2 service
import {
  ServiceAction as Sample2Action,
  ServiceEvent as Sample2Event,
  ServiceName as Sample2Name
} from './sample2.service.types'; // eslint-disable-line import/extensions

// import the actual service schema of the sample2 service
import sample2 from './sample2.service'; // eslint-disable-line import/extensions

// build union of types
type ServiceAction = Sample1Action | Sample2Action;
type ServiceEvent = Sample1Event | Sample2Event;
type ServiceName = Sample1Name | Sample2Name;

// create the typed broker
const broker: TypedServiceBroker<
    ServiceAction,
    ServiceEvent,
    ServiceName
  > = new TypedServiceBroker<
    ServiceAction,
    ServiceEvent,
    ServiceName
  >({ logLevel: 'info' });

// create the services and start the broker
broker.createService(sample1);
broker.createService(sample2);
broker.start();

// now the broker call/emit methods are typescript aware to your specific services
broker.emit('sample1.event2', { id: '1234' }); // no typescript error

broker.emit('sample1.event2'); // typescript error since arguments are expected

broker.emit('sample1.event2', { id: 1234 }); // typescript error since arguments are of wrong type

broker.call('sample1.hello'); // no typescript error

broker.call('sample1.hello', {}); // typescript error since this action does not take an argument

broker.call('sample1.welcome', {
      name: 'John'
    }); // no typescript error

broker.call('sample1.welcome'); // typescript error since arguments are expected

broker.call('sample1.welcome', {
      id: 1234
    }); // typescript error since wrong type of arguments are supplied

const result: PromiseLike<number> = broker.call('sample1.welcome', {
      name: 'John'
    }); // typescript error since return type is different

On VS Code and other typescript aware IDEs, code intellisense should work:

You can’t perform that action at this time.