Monday, March 7, 2016

Using typescript for create a node module, and import it as a dependency: Duplicate identifier (TS2300)

Leave a Comment

I've created a project (named data_model) with some classes useful in my other projects. I’ve created a complete gulpfile.js which not only compiles my .ts into .js but create an unified .d.ts file which exports my symbols, the file is named data_model.d.ts and will be at the root of the project.

Now, I create a second project, let’s call it my_cool_api which defines in its dependencies a dependency to the git of data_model
Running npm install, the .js files are downloaded into my node_modules

Everything is fine and colorful. But the typings folder.

my_cool_api   |—— package.json  |—— …  |—— app.ts   |—— node_modules     |—— data_model         |—— data_model.d.ts         |—— index.js          |—— lib             |—— my_class.js   |—— typings     |—— tsd.d.ts         |—— node         |—— … 

The problem here is the file data_model.d.ts because the very first lines of that file are going to make a reference to a typings folder which doesn’t exist. Let’s take a look

///<reference path=“typings/mongoose/mongoose.d.ts" />  declare module 'data_model' {   import mongoose = require('mongoose');    export class MyClass {    …   } } 

That’s the header of the .d.ts I’m generating right now. I had tried to duplicate typings folder (make it not to be ignorable by .npmignore would install that during npm install) which creates the following

 |—— package.json  |—— …  |—— app.ts   |—— node_modules     |—— data_model         |—— data_model.d.ts         |—— typings <<<<<<<<<<<<<<<<<<< ADDED             |—— tsd.d.ts               |—— node               |—— ...         |—— index.js          |—— lib             |—— my_class.js   |—— typings     |—— tsd.d.ts         |—— node         |—— … 

BUT that’s going to give me a hundred of "duplicated errors” (I guess because there are gonna be several node.d.ts files around). For example:

[16:44:33] [tsc] > /my_cool_api/typings/node/node.d.ts(1553,9): error TS2300: Duplicate identifier 'cleartext'. 

My solution right now is copying any .d.ts file I found in node_modules to my typings folder and change the first lines (the references) of the copied files to my relative typings folder.

THERE SHOULD BE A WAY TO DO THIS. (I’ve tried too with tsd link command)
Any help would be extremely appreciated.

2 Answers

Answers 1

The problem here is the file data_model.d.ts because the very first lines of that file are going to make a reference to a typings folder which doesn’t exist.

Don't do this, avoid reference paths in general, but especially so for third-party typings. Just pass the tsd.d.ts to the TypeScript compiler directly (or reference it in the tsconfig.json if you have one). You will have to reinstall the typings used in your data_model in your app typings (at least any that are externally visible). Yes this sucks, but there's hope on the horizon in the form of Typings.

Answers 2

I want to share the solution I'm currently using to solve this problem. It's possible since v0.10.8 of Visual Studio Code since it will search any *.d.ts file in your project - not just in the typings folder as it was before - and "compound" a global bunch of type definitions.

Let's say we have these projects:

  1. my-module (our own module we want to include as dependency)
  2. my-project (our project)
  3. another-project
  4. ...

my-module defines my-module.d.ts declaration file. Do not ignore it in the .npmignore so, once we import it as a dependency, npm will install not only the source but the definition file

my-project structure will be:

 |-- package.json  |-- src     |-- ...    |-- node_modules     |-- my-module        |-- my-module.d.ts        |-- lib           |-- ..  |-- typigns      |-- node.d.ts      |-- ... 

Visual Studio Code will recover, not only node.d.ts (and any file under typigns folder) but also my-module.d.ts.
Note that we do ignore (adding it in my-module/.npmignore) the typigns folder of our module, why? Because probably that would generate multiple node.d.ts, express.d.ts, etc files: one from the module and another from the project.

At this point I realized that, I was using a couple (~20) of .d.ts definition files among all my projects, so I decided the following:

First, I group every *.d.ts file (except those from my modules) in one folder, for example ~/workspace/typings-set. There will be no repeated elements: just one node.d.ts, express.d.ts, etc definition file.
Next, all my typescript projects create a symbolic link to that folder

$> ln -s ~/workspace/typings-set/typings typings 

(I call it typigns because convention)

Now, my-module and my-project has this structure

 my-module  |-- package.json  |-- src     |-- ...    |-- node_modules     |-- ...  |-- typigns =====> ~/workspace/typings-set/typings   my-project  |-- package.json  |-- src     |-- ...    |-- node_modules     |-- my-module        |-- my-module.d.ts        |-- lib           |-- ..  |-- typigns =====> ~/workspace/typings-set/typings   typings-set   |-- README.md   |-- tsd.json   |-- typigns      |-- node.d.ts      |-- express.d.ts      |-- socket.io.d.ts      |-- ... 
If You Enjoyed This, Take 5 Seconds To Share It

0 comments:

Post a Comment