Current Behavior
When defining a service using TypeScript, the service schema consists of two generic types that can be provided to facilitate support for typed "this" across actions, methods and lifecycle handlers:
interface MySettings extends ServiceSettingSchema {
myValue: number;
}
interface MyMethods {
myMethod: (this: MyThis) => void;
}
interface MyThis extends Service<MySettings> {
someProperty: string;
}
interface MySchema extends ServiceSchema<MySettings, MyThis> {}
const myServiceSchema: MySchema = {
name: 'myService',
actions: {
myAction(this: MyThis) {
this.myMethod(); // myMethod is correctly identified, because this type contains it in its definition
}
},
methods: {
myMethod(this: MyThis) {
// ...
}
},
started(this: MyThis) {
// ...
}
}
However, if we apply the same approach to a mixin that also utilises typed "this":
interface MyMixinSettings extends ServiceSettingSchema {
myMixinSetting: number;
}
interface MyMixinThisExtension {
someProperty: string;
}
interface MyMixinThis extends Service<MyMixinSettings>, MyMixinThisExtension {}
interface MyMixinSchema extends ServiceSchema<MyMixinSettings, MyMixinThis> {}
const myMixin: MyMixinSchema = {
name: '',
started(this: MyMixinThis) {
// ...
}
}
That mixin cannot be used inside the mixins array of MyService, because ServiceSchema defines mixins as Partial<ServiceSchema>[] (expands to: Partial<ServiceSchema<ServiceSettingSchema>>), and is therefore not compatible with MyMixinSchema (expands to: ServiceSchema<MyMixinSettings, MyMixinThis>).
interface MySettings extends MyMixinSettings, ServiceSettingSchema {
myValue: number;
}
interface MyMethods {
myMethod: (this: MyThis) => void;
}
interface MyThis extends MyMixinThisExtension, Service<MySettings> {
someProperty: string;
}
interface MySchema extends ServiceSchema<MySettings, MyThis> {}
const myServiceSchema: MySchema = {
name: 'myService',
mixins: [myMixin], // Typescript error is thrown here
actions: {
myAction(this: MyThis) {
this.myMethod();
}
},
methods: {
myMethod(this: MyThis) {
// ...
}
},
started(this: MyThis) {
// ...
}
}
Expected Behavior
Service should accept mixins that define their own ServiceSettingSchema and this types.
Failure Information
The problem boils down to the type of mixins property in ServiceSchema definition. This type should either ignore the specific ServiceSettingSchema and this types, or provide some mechanism for specifying their requirements (I don't know if this is possible, or at least how it could be achieved). The following adjustment resolves the issue:
interface ServiceSchema<S = ServiceSettingSchema, T = Service<S>> {
// ...
mixins?: Partial<ServiceSchema<any, any>>[];
// ... ^----^---- this resolves the problem
}
Steps to Reproduce
Use the above example with moleculer module installed. Typescript error will be indicated by the editor (and during compilation).
Context
- Moleculer version: 0.14.35
- NodeJS version: 20.15.0
- Operating System: MacOS
Failure Logs
TypeScript error
TS2322: Type MyMixinSchema is not assignable to type
Partial<ServiceSchema<ServiceSettingSchema, Service<ServiceSettingSchema>>>
Types of property created are incompatible.
Type
ServiceSyncLifecycleHandler<MyMixinThis> | ServiceSyncLifecycleHandler<MyMixinThis>[] | undefined``` is not assignable to type ServiceSyncLifecycleHandler<Service> | ServiceSyncLifecycleHandler<Service>[] | undefined`
Type ServiceSyncLifecycleHandler<MyMixinThis> is not assignable to type
ServiceSyncLifecycleHandler<Service<ServiceSettingSchema>> | ServiceSyncLifecycleHandler<Service<ServiceSettingSchema>>[] | undefined
Type ServiceSyncLifecycleHandler<MyMixinThis> is not assignable to type
ServiceSyncLifecycleHandler<Service<ServiceSettingSchema>>
Property someProperty is missing in type Service<ServiceSettingSchema> but required in type MyMixinThis
Current Behavior
When defining a service using TypeScript, the service schema consists of two generic types that can be provided to facilitate support for typed "this" across actions, methods and lifecycle handlers:
However, if we apply the same approach to a mixin that also utilises typed "this":
That mixin cannot be used inside the
mixinsarray ofMyService, becauseServiceSchemadefinesmixinsasPartial<ServiceSchema>[](expands to:Partial<ServiceSchema<ServiceSettingSchema>>), and is therefore not compatible withMyMixinSchema(expands to:ServiceSchema<MyMixinSettings, MyMixinThis>).Expected Behavior
Service should accept mixins that define their own
ServiceSettingSchemaandthistypes.Failure Information
The problem boils down to the type of
mixinsproperty inServiceSchemadefinition. This type should either ignore the specificServiceSettingSchemaandthistypes, or provide some mechanism for specifying their requirements (I don't know if this is possible, or at least how it could be achieved). The following adjustment resolves the issue:Steps to Reproduce
Use the above example with moleculer module installed. Typescript error will be indicated by the editor (and during compilation).
Context
Failure Logs
TypeScript error