tsd: install local definition file
Asked Answered
F

3

6

I have a local node package written in TypeScript, which I want to use in my actual project. Using npm, I can install local packages like this:

$ npm install --save /path/to/package

Or:

$ npm install --save /path/to/package.tar.gz

This installs the required .js files in the node_modules directory. There's also a generated .d.ts file within that package, which I'd like to install to my project (automatically linking it in typings/tsd.d.ts). But using the following command has no effect:

$ tsd install /path/to/package/package.d.ts --save

It says >> zero results. So, what is the way to install local definition files without the need of a repository?

UPDATE:

I can simply copy my d.ts file into the typings directory and my text editor (for me it's Sublime Text with the TypeScript plugin) it's able to find the declaration. The directory layout is something like this:

/my-project/
  /typings/
    tsd.d.ts - auto-generated by `tsd install`
    node/ - I've installed the node definitions
    my-package.d.ts - copied or symlinked file
  my-project.ts - I'm working here

However I've got an issue when exporting the only function in module.exports (exports = function... in TypeScript). In this case, the exported function is kinda 'anonymous' and isn't even named in the d.ts file, so I need to edit it manually.

My test case:

'my-package' provides a single function, usually imported as 'myPackage':

export = function myPackage(a: string, b: string) { return a + ' ' + b; };

declaration is set to true in tsconfig.json, so the tsc command generated a my-package.d.ts file:

declare var _default: (a: string, b: string) => string;
export = _default;

My package is supposed to be used like this in my project:

import myPackage = require('my-package');
myPackage('foo', 'bar');

However, tsc can't find myPackage, even though my-package.d.ts was copied into the typings folder. I need to edit that file so it looks like this:

declare var myPackage: (a: string, b: string) => string;
//export = _default; - not needed

Or even better for a correct functioning require():

declare module 'my-package' /* this is the string passed to require() */ {
    export = function(a: string, b: string): string;
}
Felix answered 2/1, 2016 at 19:10 Comment(2)
importing the d.ts files from the node_modules (I just copied a file there) seems to work just fine for me, there's no need for tsd to do anything.Kame
you're right, toskv, I can simply copy the d.ts file without the need of referencing it in typings/tsd.d.ts. I encountered an issue if I set the exports variable, I've updated my post with more information about this.Felix
A
6

In your local node package, add a typescript > definition entry in package.json:

{
  "name": "your-package",
  ...
  "typescript": {
    "definition": "package.d.ts"
  }
}

Then after installing the package in your project, run the command...

tsd link

...which will add a reference to package.d.ts in your project's tsd.d.ts file (reference).


Also, based on your edit, I would suggest you change your definition file to something like this (note the quotes around my-package):

declare module "my-package" {
    function myPackage(a: string, b: string): string;
    export = myPackage;
}

That will make it work with the following code:

import myPackage = require('my-package');
myPackage('foo', 'bar');
Aluino answered 2/1, 2016 at 20:55 Comment(4)
thanks, it worked! however, my TypeScript source (with typings) is in a separate directory from the compiled JavaScript (with package.json and node_modules), is there a way to get it working here as well?Felix
@Felix I'm not exactly sure what you mean. With this setup, you only have to make sure the definition file of the package is included with the package (no need to include the typescript source of the package). Doing this will add something like /// <reference path="../node_modules/your-local-package/package.d.ts" /> to ~/typings/tsd.d.ts in your application. As long as that definition file contains all the necessary information it should compile fine at that point. By the way, based on your edit, see my edit about changing the definition file... I know the way I show here works.Aluino
I'm not sure if I don't get your point or you're not getting my point here. However, taking your latest edit with declare module ... and simply copying the d.ts file to my project's typings folder works perfectly now!Felix
@Felix I think I'm not understanding haha :) Well, it's great it ended up working!Aluino
L
8

Even if the trick with package.json is working, I rather prefer the tools made for that (tsd or typings).

I just found the answer for Typings :
typings install --save --ambient file:./node_modules/.../file.d.ts

I think it's the same with tsd :)

EDIT:
Since TypeScript 2.0 typings is useless.
Just run npm i --save-dev @types/some-library

Lomax answered 9/2, 2016 at 19:13 Comment(2)
--ambient is now replaced by --global (tested on v1.3.2)Encomium
What's the equivalent of this for TypeScript 2's new approach to acquiring type definition files (npm install @types/...)? You can typings install file:... to install a single type definition file, but you can only npm install a package.Tubing
A
6

In your local node package, add a typescript > definition entry in package.json:

{
  "name": "your-package",
  ...
  "typescript": {
    "definition": "package.d.ts"
  }
}

Then after installing the package in your project, run the command...

tsd link

...which will add a reference to package.d.ts in your project's tsd.d.ts file (reference).


Also, based on your edit, I would suggest you change your definition file to something like this (note the quotes around my-package):

declare module "my-package" {
    function myPackage(a: string, b: string): string;
    export = myPackage;
}

That will make it work with the following code:

import myPackage = require('my-package');
myPackage('foo', 'bar');
Aluino answered 2/1, 2016 at 20:55 Comment(4)
thanks, it worked! however, my TypeScript source (with typings) is in a separate directory from the compiled JavaScript (with package.json and node_modules), is there a way to get it working here as well?Felix
@Felix I'm not exactly sure what you mean. With this setup, you only have to make sure the definition file of the package is included with the package (no need to include the typescript source of the package). Doing this will add something like /// <reference path="../node_modules/your-local-package/package.d.ts" /> to ~/typings/tsd.d.ts in your application. As long as that definition file contains all the necessary information it should compile fine at that point. By the way, based on your edit, see my edit about changing the definition file... I know the way I show here works.Aluino
I'm not sure if I don't get your point or you're not getting my point here. However, taking your latest edit with declare module ... and simply copying the d.ts file to my project's typings folder works perfectly now!Felix
@Felix I think I'm not understanding haha :) Well, it's great it ended up working!Aluino
C
1

As of TypeScript 1.6 you can reference your type definition file from you package.json and TypeScript's module resolution should be able to dig out the type definition.

In your package.json file (of your local npm module), add a "typings" entry, e.g.

{
    "name": "my-package",
    "typings": "./relative/path/to/my-package.d.ts"
}

This way you don't need to fiddle with TSD at all.

See TypeScript Wiki: https://github.com/Microsoft/TypeScript/wiki/Typings-for-npm-packages

Cathar answered 3/1, 2016 at 3:15 Comment(1)
"types" is now the suggested usage (though "typings" is still synonymous). Also wiki link updateSpline

© 2022 - 2024 — McMap. All rights reserved.