7
votes

I'm building a typescript project and using a non-typescript lib call 'draggabilly';

So I'm trying to declare it by myself.

Here is the file structure:

├── @types
│   └── draggabilly
│       └──index.d.ts
├── node_modules
├── package.json
├── README.md
├── src
│   ├── index.ts
│   └── application.ts
└── tsconfig.json

src/application.ts

import * as Draggabilly from 'draggabilly';

new Draggabilly('#dragItem', {
  // options...
});

......

it's showing that

Could not find a declaration file for module 'draggabilly'. '/node_modules/draggabilly/draggabilly.js' implicitly has an 'any' type.

So I try to create the local declaration file: @types/draggabilly/index.d.ts:

export as namespace draggabilly;

export = Draggabilly;

declare class Draggabilly {
  constructor(selector: string, options: any);
}

then include the types path in tsconfig.json:

{
    "compilerOptions": {
        ......
        "typeRoots": [
            "./node_modules/@types",
            "./@types"
        ]
    }
}

But the error still there. So I want to know what's wrong here and what's the correct way to build the third party module declare file locally

I created a demonstration repository for this question on github: https://github.com/ZheFeng/test-ts-types

The issue is not only about how we define inside the .d.ts file, but also the typescript could not find a declaration file at all.

2
Checkout this draggabilly typings github.com/giespaepen/draggabilly/blob/…Aivan Monceller
Thanks Aivan, I did. But typescript seems didn't recognize my declaration file. That's why I put my file structure and config above.Zhe

2 Answers

4
votes

The problem is in the line export = Draggabilly; -- you have to use the TypeScript-specific syntax import let = require("module") to import it:

From the TypeScript documentation:

When importing a module using export =, TypeScript-specific import let = require("module") must be used to import the module.

So your import should be:

import Draggabilly = require("draggabilly");


index.d.ts
export as namespace draggabilly;

export class Draggabilly {
  constructor(selector: string, options: any);
}

... and import it like this:

import * as draggabilly from 'draggabilly';

new draggabilly.Draggabilly('#dragItem', {
  // options...
});
2
votes

When providing declaration file for the 3rd party module that is non-TypeScript based, the declare module must be in the global scope, and no import or export outside the declare module.

@types/draggabilly/index.d.ts

declare module "draggabilly" {
    // import other libraries, optional
    // ...

    class Draggabilly {
        constructor(selector: string, options: any);
    }

    export = Draggabilly;
}

src/application.ts

import Draggabilly = require("draggabilly");

new Draggabilly("#dragItem", {
    // options...
});