TypeScript custom declaration files for untyped npm modules

ReactjsTypescriptEcmascript 6Visual Studio-Codetypescript2.0

Reactjs Problem Overview


I am consuming a React component called shiitake from npm into my project where I use TypeScript. That library does not have TypeScript declarations so I thought I would write one. The declaration file looks like below (it may not be complete but don't worry about it too much):

import * as React from 'react';

declare module 'shiitake' {

    export interface ShiitakeProps {
        lines: number;
    }

    export default class Shiitake extends React.Component<ShiitakeProps, any> { 
    }
}

I have put this inside ./typings/shiitake.d.ts file and on VS Code, I am seeing the below error:

> [ts] Invalid module name in augmentation. Module 'shiitake' resolves to an untyped module at 'd:/dev/foo/foobar.foo.Client.Web/node_modules/shiitake/dist/index.js', which cannot be augmented.

On the consumption side, I am still getting the same error even if with the above declaration (since I have noImplicitAny compiler switch turned on):

/// <reference path="../../../../typings/shiitake.d.ts" />
import * as React from 'react';
import Shiitake from 'shiitake';

> [ts] Could not find a declaration file for module 'shiitake'. 'd:/dev/foo/foobar.foo.Client.Web/node_modules/shiitake/dist/index.js' implicitly has an 'any' type.

The standard why of acquiring declaration files for this type of modules is through @types/ way and it works well. However, I cannot get the custom typings work. Any thoughts?

Reactjs Solutions


Solution 1 - Reactjs

The declaration declare module 'shiitake'; should be in a global scope. i.e. a top-level declaration in a non-module (where a module is a file with at least one top-level import or export).

A declaration of the form declare module '...' { } in a module is an augmentation. For more details see Typescript Module Augmentation.

So you want this file to look like this:

declare module 'shiitake' {

    import * as React from 'react';

    export interface ShiitakeProps {
        lines: number;
    }

    export default class Shiitake extends React.Component<ShiitakeProps, any> { 
    }
}

Solution 2 - Reactjs

In my experience, a definition file will fail in this way if it has any exports or imports declared outside the module definition. If you use an IDE with auto-import, be warned!

Solution 3 - Reactjs

I had the same problem today.

Turns out I paste exported interfaces outside of the module declaration. The typings file I used as a template had private interfaces at the end of the file.

So my exported interfaces were declared outside of the module declaration. This is drives typescript compiler nuts.

Once I moved the interfaces into the module boundaries everything got fixed.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestiontugberkView Question on Stackoverflow
Solution 1 - Reactjsmohamed hegazyView Answer on Stackoverflow
Solution 2 - ReactjsEd StaubView Answer on Stackoverflow
Solution 3 - ReactjsSergey DryganetsView Answer on Stackoverflow