-
Notifications
You must be signed in to change notification settings - Fork 44
Description
Hi, at the moment it seems like there is no way to override the type for this parameter for the lifecycle methods (created , started and stopped). In consequence, it's impossible to create those methods if they implement a custom this (similarly to how methods and actions do it).
This can be temporarily ignored as suggested in #67, but that's a workaround and not a fix.
I'm realtively new to typescript so I might be missing some obvious solution / best practices related to this, but I think the following could work:
index.d.ts
// ...
type ServiceSyncLifecycleHandler<S = ServiceSettingSchema> = (this: Service<S>) => void;
type ServiceAsyncLifecycleHandler<S = ServiceSettingSchema> = (this: Service<S>) => void | Promise<void>;
interface ServiceSchema<S = ServiceSettingSchema> {
name: string;
version?: string | number;
settings?: S;
dependencies?: string | ServiceDependency | (string | ServiceDependency)[];
metadata?: any;
actions?: ServiceActionsSchema;
mixins?: Partial<ServiceSchema>[];
methods?: ServiceMethods;
hooks?: ServiceHooks;
events?: ServiceEvents;
created?: ServiceSyncLifecycleHandler<S> | ServiceSyncLifecycleHandler<S>[];
started?: ServiceAsyncLifecycleHandler<S> | ServiceAsyncLifecycleHandler<S>[];
stopped?: ServiceAsyncLifecycleHandler<S> | ServiceAsyncLifecycleHandler<S>[];
[name: string]: any;
}
// ...should be changed to:
index.d.ts
// ...
type ServiceSyncLifecycleHandler<S = ServiceSettingsSchema, T = Service<S>> = (this: T) => void;
type ServiceAsyncLifecycleHandler<S = ServiceSettingSchema, T = Service<S>> = (this: T) => void | Promise<void>;
interface ServiceSchema<S = ServiceSettingSchema, T = void> {
name: string;
version?: string | number;
settings?: S;
dependencies?: string | ServiceDependency | (string | ServiceDependency)[];
metadata?: any;
actions?: ServiceActionsSchema;
mixins?: Partial<ServiceSchema>[];
methods?: ServiceMethods;
hooks?: ServiceHooks;
events?: ServiceEvents;
created?: ServiceSyncLifecycleHandler<S, T> | ServiceSyncLifecycleHandler<S, T>[];
started?: ServiceAsyncLifecycleHandler<S, T> | ServiceAsyncLifecycleHandler<S, T>[];
stopped?: ServiceAsyncLifecycleHandler<S, T> | ServiceAsyncLifecycleHandler<S, T>[];
[name: string]: any;
}
// ...The above code is meant to provide a way to supply additional type for this parameter at the service declaration level (e.g. in greeter.service.ts), which would change it from:
export interface GreeterSettings extends ServiceSettingSchema {
defaultName: string;
}
export interface GreeterMethods {
uppercase(str: string): string;
}
export type GreeterThis = Service<GreeterSettings> & GreeterMethods;
const GreeterService: ServiceSchema<GreeterSettings> = {
name: "greeter",
settings: {
defaultName: "Moleculer",
},
dependencies: [],
actions: {},
events: {},
methods: {
uppercase(str: string) {
return str.toUpperCase()();
},
},
created(this: GreeterThis) { // <-- This does not work
console.log(this.broker.services);
},
async started(this: GreeterThis){ // <-- This does not work
this.uppercase('hello world');
},
async started(this: GreeterThis){ // <-- This does not work
this.uppercase('goodbye world');
},
};to
export interface GreeterSettings extends ServiceSettingSchema {
defaultName: string;
}
export interface GreeterMethods {
uppercase(str: string): string;
}
export type GreeterThis = Service<GreeterSettings> & GreeterMethods;
const GreeterService: ServiceSchema<GreeterSettings, GreeterThis> = { // <-- This is the actual change
// in service declaration
name: "greeter",
settings: {
defaultName: "Moleculer",
},
dependencies: [],
actions: {},
events: {},
methods: {
uppercase(str: string) {
return str.toUpperCase()();
},
},
created(this: GreeterThis) {
console.log(this.broker.services);
},
async started(this: GreeterThis){
this.uppercase('hello world');
},
async started(this: GreeterThis){
this.uppercase('goodbye world');
},
};Please let me know if you'd like me to create a PR with this change.