#Using a declaration file to type-check a JS Mixin

3 messages · Page 1 of 1 (latest)

dapper schooner
#

I've got a class that uses my own mixin and a mixin that comes with an API. Both mixins function essentially the same way.

// API
function APIMixin(Base) {
  return class APIClass extends Base {}
}

// SheetMixinV2.js
function Mixin(Base) {
  return class MixedClass extends Base {}
}

// CharacterSheetV2.js
export default class Composite extends APIMixin( MyMixin(GlobalClass) ) { ... }

This is how HandlebarsApplicationMixin is documented, which works and shows the members of HandlebarsApplication and any base class you pass through the mixin function:

// API
type AnyConstructor = abstract new (arg0: never, ...args: never[]) => unknown;
type AnyConcreteConstructor = new (arg0: never, ...args: never[]) => unknown;
type ConstructorOf<T> = new (arg0: never, ...args: never[]) => T;

type Mixin<MixinClass extends AnyConcreteConstructor, BaseClass extends AnyConstructor> = MixinClass & BaseClass;

declare function APIMixin<T extends ConstructorOf<GlobalClass.Internal<any, any, any>>>(
    Base: T,
): Mixin<typeof APIClass<T>, T>;

// types.d.ts
declare function Mixin<T extends ConstructorOf<GlobalClass.Internal<any, any, any>>>(
    Base: T
): Mixin<typeof MixedClass<T>, T>

But when I do the same for SheetMixinV2, the inheritance breaks and I can't get type-checking on either HandlebarsApplication or ActorSheetV2. I apologize for the type gymnastics, most of this isn't my own ^^;;
How could I get my mixin to preserve the inheritance of base classes? Since I'm just using d.ts files, I need to include some sort of signature but every tutorial I find on TS Mixins don't implicitly write out the return type.

dapper schooner
#

Here, I'll rename everything to make it more clear

dapper schooner
#

Found out there were d.ts compilation on the playground. Here's the solution:

type Constructor<T = {}> = new (...args: any[]) => T

type InstanceMembers = {
  foo: string
}
type StaticMembers = {
  bar: string
}

declare function MixinFunction<T extends Constructor>(Base: T):
  ((new (...args: any[]) => InstanceMembers) & StaticMembers) & T