2

I'm trying to integrate a JavaScript library (bricks.js) that has no publicly available type definition.

Basically, what the library is exporting is something like this:

export default (config) => {

    const instance = SomeConstructorFunction(config);
    return instance;
}

I cannot figure out how to correctly create a type definition (.d.ts) for this function; either tsc compiles when I import, I get undefined or tsc won't compile.

For this instance .d.ts compiles:

declare module 'bricks.js' {
    export class Bricks {
         constructor(config: any);
         pack(); // some function available on the instance
   }
}

But if I import like this, inside my AngularJs 2 component:

import { Bricks } from 'bricks.js';
this.bricks = new Bricks({//some config here});

Then Bricks is undefined, hence an error is thrown :-).

I don't get exactly how to build a .d.ts for that library; furthermore, the library is compiled using Babel, and I suspect Babel does something with arrow function default exports...

5
  • how are you using this lib inside your code without angular2? i.e in jquery you just $().. Commented Jun 5, 2016 at 8:46
  • since the export is default you don't need the { } when importing, try writing import Bricks from 'bricks.js'/ Commented Jun 5, 2016 at 8:57
  • @echonax like that new Bricks({...}) Commented Jun 5, 2016 at 9:20
  • @toskv I'm out so I can't post the exact error but when I did ´import Bricks from 'bricks.js'´tsc didn't compile because there was no defaut export, I guess I've got to write something more in the .d.ts Commented Jun 5, 2016 at 9:22
  • In fact if I compile like I've posted and then I change the import in my component to something like import * as Bricks from 'bricks.js' then it works when the component is hot reloaded. But if I try to compile again then tsc will complain :-/ Commented Jun 5, 2016 at 9:28

2 Answers 2

1

Ok, found my way through this little nightmare...

The bricks.js library is defined using ES6 modules (src folder) but is also built using Babel.

I'm using Systemjs to load my Angular2 project dependencies,

So basically I've got two options from there:

  • use the ES6 bricks.js from the src folder. That means using the modern typescript syntax for loading ES6 modules and then declare a transpiler in the Systemjs config so that it can load the library and its dependencies correctly.

  • or use the Babel transpiled bricks.min.js from the dist folder. I have to use the non-module entity syntax.

See https://stackoverflow.com/a/29598404/254439

I went with the second solution to avoid transpilation from Systemjs.

So here is what I did:

.index.d.ts

declare module 'bricks.js' {
    interface Bricks {
        pack();
    }

    function bricksFactory(config:any): Bricks

    export = bricksFactory;

}

systemjs.config.js

...
var map = {
    ...
    'bricks.js':                  'node_modules/bricks.js/dist/'
    ...
}
...
var packages = {
    ...
    'bricks.js':                  { main: 'bricks.min.js', defaultExtension: 'js'}
};

my.component.ts

import bricksFactory = require('bricks.js');

this.bricksInstance =  Bricks({
    container: '.mycontainer',
    packed: 'data-packed',
    sizes: [
        { columns: 2, gutter: 10 },
        { mq: '768px', columns: 3, gutter: 25 },
        { mq: '1024px', columns: 4, gutter: 50 }
    ]
});
Sign up to request clarification or add additional context in comments.

Comments

0

You can import the code using import * as Bricks from 'bricks.js';

You can define it using something like

declare module "Bricks" {
  function loadConfig(config): SomeConstructorFunction;
    var _tmp = loadConfig;
   export = _tmp;
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.