microsoft / TypeScript

TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
https://www.typescriptlang.org
Apache License 2.0
100.75k stars 12.46k forks source link

Duplicate identifiers #6475

Closed davidleureka closed 8 years ago

davidleureka commented 8 years ago

I'm having an issue with duplicate identifier errors. It appears to stem from having the same definitions listed in multiple places.

Let's say that I have a simple node server that utilizes the bluebird promise library. I have bluebird used in the main server code and in a library I wrote used by the server code. The structure looks like this:

|-- server.ts
|-- tsd.json
|-- typings
|-- lib
    |-- mylib.ts
    |-- tsd.json
    |-- typings

Here is the code for and for mylib.ts:

/// <reference path="./typings/tsd.d.ts"/>
import Promise = require('bluebird')
class MyLib {
}
export = MyLib

and server.ts:

/// <reference path="./typings/tsd.d.ts"/>
import Promise = require('bluebird')
import MyLib = require('./lib/mylib')
class Server {
}
export = Server

As you can see, both server.ts and mylib.ts use the bluebird library. Since server.ts uses mylib.ts, it ends up importing bluebird twice, which results in errors. So when I run

tsc server.ts --module commonjs

I get

lib/typings/bluebird/bluebird.d.ts(705,9): error TS2300: Duplicate identifier 'concurrency'. lib/typings/bluebird/bluebird.d.ts(708,9): error TS2300: Duplicate identifier 'spread'. lib/typings/bluebird/bluebird.d.ts(711,9): error TS2300: Duplicate identifier 'suffix'. typings/bluebird/bluebird.d.ts(705,9): error TS2300: Duplicate identifier 'concurrency'. typings/bluebird/bluebird.d.ts(708,9): error TS2300: Duplicate identifier 'spread'. typings/bluebird/bluebird.d.ts(711,9): error TS2300: Duplicate identifier 'suffix'.

Tools like npm seem to be able to handle this situation. The only way I can get typescript to handle it is by having a single tsd.json file and corresponding typings folder at the root of my project and having all the typescript definitions live there. Is that the generally accepted way to structure things?

born2net commented 8 years ago

+1 + 1 + 1... please add ignoreDups flag

mhegazy commented 8 years ago

The duplicate identifier is a symptom of another issue. i would like to understand the issue a bit more. Can you elaborate on why you need to copies of bluebird.d.ts (lib/typings/bluebird/bluebird.d.ts and typings/bluebird/bluebird.d.ts), why not have two tsconfig.json and call the compiler twice, once for lib, and once for server?

born2net commented 8 years ago

I beleive the issue has to do with the trasnpiler not respecting the exclude as in:

 "exclude": [
    "node_modules",
    "/node_modules",
    "../node_modules",
    "*node_modules*",
    "/node_modules*",
    "angular2",
    "rxjs",
    "typings"
  ],

since as you can see from my attached image, all issues are a result of the TS still inspecting the node_modules dir

capture

mhegazy commented 8 years ago

"exclude" only excludes files in your folder, and its subfolders from being automatically included int he compilation. if you import a module in your code, the compiler will have to pull it in (e.g. import {..} from "angular2\angular2"). if you want to disable this use--noResolve`.

can you share your project so that i can understand the project setup?

born2net commented 8 years ago

sure: https://github.com/born2net/ng2Boilerplater-webpack

born2net commented 8 years ago

FYI noResolve the core libs wont resolve... aa

davidleureka commented 8 years ago

@mhegazy, it's quite possible that I'm simply not using the compiler the way it was intended to be used. I'm actually using the one built into WebStorm. My (probably incorrect) assumption was that I could compile my "main" file (server.ts) and the compiler would handle the references to other code recursively. Similar to how it works in a language like C++ with #include statements.

Can you elaborate more on your recommendation on how it should be structured? An example or reference would be helpful.

mhegazy commented 8 years ago

@born2net I think i understand the issue now. the main problem is that two packages you are including angular2 and ng2-translate both introduce the same global scope definitions.

//CC @alexegel from the angular2 team if he has any recommendations here.

Additionally, you were including locally some typings files, like node.d.ts that angular2 packages ships another verison of.

I have a PR out for your repo to work around that and demonstrate the issue at: https://github.com/born2net/ng2Boilerplater-webpack/pull/1

At the core, this is the same issue as https://github.com/Microsoft/TypeScript/issues/4665. @vladima is looking into a fix here.

mhegazy commented 8 years ago

@davidleureka can you share your project setup, so that i can understand the problem before making any recommendations.

born2net commented 8 years ago

tx will check asap!

DanielRosenwasser commented 8 years ago

@alexeagle

born2net commented 8 years ago

I applied your changes but still same dup errors :(

mhegazy commented 8 years ago

i built using tsc. how are you building?

born2net commented 8 years ago

I am building using WebStorm which ships with TS 1.7 https://github.com/born2net/ng2Boilerplater-webpack, same issues :(

mhegazy commented 8 years ago

note sure what is going on.. but here is what i see locally:

c:\test\ng2-webpack\ng2Boilerplater-webpack>git status
On branch master
Your branch is up-to-date with 'remote/master'.
nothing to commit, working directory clean

c:\test\ng2-webpack\ng2Boilerplater-webpack>git remote
origin
remote

c:\test\ng2-webpack\ng2Boilerplater-webpack>git remote -v
origin  https://github.com/born2net/ng2Boilerplater-webpack.git (fetch)
origin  https://github.com/born2net/ng2Boilerplater-webpack.git (push)
remote  https://github.com/mhegazy/ng2Boilerplater-webpack.git (fetch)
remote  https://github.com/mhegazy/ng2Boilerplater-webpack.git (push)

c:\test\ng2-webpack\ng2Boilerplater-webpack>node c:\releases\1.7.3\tsc.js  --v
message TS6029: Version 1.7.3

c:\test\ng2-webpack\ng2Boilerplater-webpack>node c:\releases\1.7.3\tsc.js  --p .\

c:\test\ng2-webpack\ng2Boilerplater-webpack>echo %ERRORLEVEL%
0
born2net commented 8 years ago

re-compiled and LOOKS GOOD now... TX for the help!!!!

alexeagle commented 8 years ago

Angular 2 generally causes problems for some users by bundling dependent typings. However, that is a great convenience for beginning users, who otherwise need to know which typings angular 2 uses, and bring them manually (eg. with tsd) Long-term we hope to have a package-scoping feature for TypeScript, so that angular 2 can bundle its dependencies but they are not visible outside of our own import/references. Shorter term we still need to determine an answer, either github.com/typings or maybe a different distribution or entry point without the bundled typings.

maxime1992 commented 8 years ago

@born2net I didn't understand how you solved it, can you please give some more details ?

largeDachshund commented 8 years ago

What got fixed here? We're doing a la carte fixes to people's projects??

This is a big problem. Only going to get worse as more folks jump on the Angular 2 bandwagon.

I'm using ng2-datepicker and Angular 2 beta 2. I get they're both somehow complaining about moment.js.

Can you provide some constructive steps to avoid these collisions?

Thanks,

alexeagle commented 8 years ago

Angular 2 beta.6 no longer pollutes the type-checker with typings from our dependencies. If you just have Angular 2 problems, the upgrade should fix duplicate identifiers.

As Mohamed said earlier https://github.com/Microsoft/TypeScript/issues/6475#issuecomment-171751611 there is now work going on that would improve the duplicate identifiers problem in the general case.

moshie commented 7 years ago

image

looks like phantom js & node typings are conflicting figure it's related to this issue

alexeagle commented 7 years ago

@moshie you should bring that up with the maintainers of the phantomjs typings, that's not a TypeScript nor Angular issue.