jantimon jantimon - 2 months ago 9
TypeScript Question

Typescript definition for an add mixin function

Is there a way to write a Typescript definition for the following mix-in helper?

I've this pattern in library.js, and I'd like to create the library.d.ts

// declaration in `library.js`
var mixin = {
example: function {}
}

function addMixin(instance) {
instance.example = mixin.example;
return example;
}

// usage in `client.js`
class MyClass {}
let myInstance = addMixin(new MyClass());

Answer

One possible way is to declare addMixin with generic type parameter T, and declare addMixin return type as intersection type of T with mixin type.

For this to work, addMixin parameter has to be declared somehow to allow an assignment to example property - again, intersection type, but this time with optional example property could do the trick.

Then, you have to use type cast for addMixin return value - it would be nice to have some kind of type guard to be able to express that it always has an example property after assignment, but type cast will do it for now. (I assume you want to return instance from it, return example in your question gives an error about undefined example).

So, addMixin implementation in typescript could look like

var mixin = {
    example: function () { }
};

function addMixin<T>(instance: T & { example?() }): T & { example() } {
    instance.example = mixin.example;
    return instance as T & { example() };
}

If the actual implementation is in javascript and you just need declaration file for it, it can look like

// declaration in library.d.ts
declare function addMixin<T>(instance: T & { example?() }): T & { example() };

// implementation in library.js
var mixin = {
    example: function() {}
};

function addMixin(instance) {
  instance.example = mixin.example;
  return instance;
}


// can be used in client.ts with library.d.ts
// tsc client.ts library.d.ts

class MyClass {}
let myInstance = addMixin(new MyClass());

myInstance.example();