Skip to content

What is the correct way to write a .d.ts file for a node module, which is referenced in package.json? #8335

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
0815fox opened this issue Apr 27, 2016 · 12 comments
Labels
Docs The issue relates to how you learn TypeScript @types Relates to working with .d.ts files (declaration/definition files) from DefinitelyTyped

Comments

@0815fox
Copy link

0815fox commented Apr 27, 2016

So, i am working on a small module written in JS, but I want to make it easy to use that module in TypeScript as well. It adds a wrapper with some additional functionality around an existing JS module.

In my module path i have package.json with:

{
  "name": "parallel-nock",
  "version": "0.0.1",
  "description": "Adds a wrapper around nock, which allows to use it more efficiently in parallel tests.",
  "main": "index.js",
  "typings": "index.d.ts",
...
  "dependencies": {
    "bluebird": "^3.3.5",
    "nock": "^8.0.0"
  }
}

index.js is a very simple module, exporting just a function:

'use strict';
var Promise = require('bluebird');
var nock = require('nock');

var scopePromises = {};

function extendScope(Url) {
  return new Promise(function(resolve){
    scope = Object.create(nock(Url));
    scope.release = function() {
      resolve(scope);
    };
  };
}

function parallelNock(Url) {
  var scopePromise = scopePromises[Url];
  if (scopePromise) {
    scopePromise = scopePromise.then((Scope){
      return extendScope;
    });
  } else {
    scopePromise = extendScope(Url);
  }
  scopePromises[Url] = scopePromise;
}

module.exports = parallelNock;

And index.d.ts is:

declare module "parallel-nock" { 
  import nock = require('nock');

  namespace parallelNock {
    export function release():void;
  }

  function parallelNock (host: string, options?: any): any;
  export = parallelNock;
}
  • when I import that module into my project:
import parallelnock = require('parallel-nock');

, I get:

$ tsc
test.ts(4,31): error TS2656: Exported external package typings file '/home/mk/work/4.5.1/workspace2/cloud/node_modules/parallel-nock/index.d.ts' is not a module. Please contact the package author to update the package definition.
  • I found no "official" resource on how to write a correct .d.ts file, especially for a "module" which only exports a function.
  • I found [http://stackoverflow.com/questions/24029462/how-to-you-write-a-typescript-definition-file-for-a-node-module-that-exports-a-f](this on stackoverflow) but it seems not to work.
  • I oriented on the [https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/nock/nock.d.ts](typings file from the nock module I used) on DefinitelyTyped, which seems to do something very similar.
  • I am confused now.
@mhegazy
Copy link
Contributor

mhegazy commented Apr 27, 2016

change your .d.ts file to be a module (i.e. a top level import or export), so it would look like:

import nock = require('nock');

declare namespace parallelNock {
    export function release():void;
}

declare function parallelNock (host: string, options?: any): any;
export = parallelNock;

@mhegazy
Copy link
Contributor

mhegazy commented Apr 27, 2016

we have some documentation about exposing types in npm at: http://www.typescriptlang.org/docs/handbook/typings-for-npm-packages.html

that could definitely be better though. we are working on updating the typing acquisition story, so i will leave this issue open until that is done.

@mhegazy
Copy link
Contributor

mhegazy commented Apr 27, 2016

for completeness, here is the guide for writing definition files: http://www.typescriptlang.org/docs/handbook/writing-declaration-files.html

@mhegazy mhegazy added Docs The issue relates to how you learn TypeScript @types Relates to working with .d.ts files (declaration/definition files) from DefinitelyTyped labels Apr 27, 2016
@0815fox
Copy link
Author

0815fox commented Apr 27, 2016

Oh, thank you for the valuable input, @mhegazy.
Those guides did not help me to get the correct definition file. But I can follow you, so if I got it right, the folder containing the package.json becomes a module, when the .d.ts file, which typings in package.json points to, contains a top level import, which makes it an external module...

About documentation... well, I know, theres always not enough time... Anyway, what you already have is already very valuable.

@mhegazy
Copy link
Contributor

mhegazy commented Apr 27, 2016

correct. and the name of the module that users import with is the name of the package. The logic should follow the same node package logic, i.e. index.d.ts would do, otherwise you need to specify "typings" entry, like you do with "main". so your package can look like

- parallelNock
| - package.json 
| - index.js
| - index.d.ts

or

- parallelNock
| - package.json  // "main": ".\lib\index.js", "typings" : ".\lib\index.d.ts"
| - lib
    | - index.js
    | - index.d.ts

@alexicum
Copy link

I did next:

  1. put index.d.ts for my package into \typings\globals
  2. made update to \typings\index.d.ts:
    /// <reference path="globals/<PackageName>/index.d.ts" />
    and this helped to avoid TS2656 without using top level export.
    Is it correct way?

@0815fox
Copy link
Author

0815fox commented Jun 28, 2016

In case you use typings, you should rather let it do that for you. You can use

typings install file:/path/to/file --save-dev

to add a dependency to a local type definition (refer to typings.json or index.d.ts) or you create a github-repository and fetch it from there.

@Yunnkii
Copy link

Yunnkii commented Aug 3, 2018

react markdown use in Typescript.
error: TS2604: JSX element type 'Markdown' does not have any construct or call signatures

import * as Markdown from 'react-markdown';

<Markdown source={this.state.content} skipHtml={true} />
tsconfig.json:

{
  "compilerOptions": {
    "sourceMap": true,
    "module": "es6",
    "target": "es6",
    "lib": [
      "dom",
      "es7"
    ],
    "jsx": "preserve",
    "strict": true,
    "noImplicitAny": true,
    "moduleResolution": "node",
    "baseUrl": "src",
    "keyofStringsOnly": true,
    "allowSyntheticDefaultImports": true,
    "experimentalDecorators": true,
    "esModuleInterop": true,
    "typeRoots" : [
      "node_modules/@types/",
      "./typings/markdown.d.ts",
      "./typings/typings.d.ts"
    ]
  },
  "include": [
    "./src/**/*",
    "./typings/markdown.d.ts",
    "./typings/typings.d.ts"
  ],
  "exclude": [
    "node_modules",
    "dist"
  ]
}

markdown.d.ts:

declare function Markdown(props: any): any; export = Markdown;

Anyone konws how to resolve it?
Thanks very much!
i don not know why.
@mhegazy

@mhegazy
Copy link
Contributor

mhegazy commented Aug 3, 2018

use:

import Markdown from 'react-markdown';

@Yunnkii
Copy link

Yunnkii commented Aug 3, 2018

Thank you ,It doesn't report an error,but markdown file doesn't render .
just render blank , not markdown file
@mhegazy

@oleersoy
Copy link

oleersoy commented Jul 15, 2019

Trying to follow the tips given here, but not quite getting any traction. Thoughts?

https://stackoverflow.com/questions/57032253/providing-an-index-d-ts-file-for-canonical-json

mathiasrw added a commit to mathiasrw/bsv that referenced this issue Mar 22, 2020
@dharnil
Copy link

dharnil commented Feb 24, 2024

change your .d.ts file to be a module (i.e. a top level import or export), so it would look like:

import nock = require('nock');

declare namespace parallelNock {
    export function release():void;
}

declare function parallelNock (host: string, options?: any): any;
export = parallelNock;

Hi @mhegazy,

I am a noob programmer. I need to know how did you find this information or and link to the docs?

Any help is much appreciated.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Docs The issue relates to how you learn TypeScript @types Relates to working with .d.ts files (declaration/definition files) from DefinitelyTyped
Projects
None yet
Development

No branches or pull requests

7 participants