{"action":"created","issue":{"url":"https://api.github.com/repos/Microsoft/TypeScript/issues/2839","labels_url":"https://api.github.com/repos/Microsoft/TypeScript/issues/2839/labels{/name}","comments_url":"https://api.github.com/repos/Microsoft/TypeScript/issues/2839/comments","events_url":"https://api.github.com/repos/Microsoft/TypeScript/issues/2839/events","html_url":"https://github.com/Microsoft/TypeScript/issues/2839","id":69690167,"number":2839,"title":"External module resolution for non-Typescript packages","user":{"login":"poelstra","id":1025628,"avatar_url":"https://avatars.githubusercontent.com/u/1025628?v=3","gravatar_id":"","url":"https://api.github.com/users/poelstra","html_url":"https://github.com/poelstra","followers_url":"https://api.github.com/users/poelstra/followers","following_url":"https://api.github.com/users/poelstra/following{/other_user}","gists_url":"https://api.github.com/users/poelstra/gists{/gist_id}","starred_url":"https://api.github.com/users/poelstra/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/poelstra/subscriptions","organizations_url":"https://api.github.com/users/poelstra/orgs","repos_url":"https://api.github.com/users/poelstra/repos","events_url":"https://api.github.com/users/poelstra/events{/privacy}","received_events_url":"https://api.github.com/users/poelstra/received_events","type":"User","site_admin":false},"labels":[{"url":"https://api.github.com/repos/Microsoft/TypeScript/labels/Suggestion","name":"Suggestion","color":"006b75"}],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":8,"created_at":"2015-04-20T21:54:53Z","updated_at":"2015-04-22T01:54:30Z","closed_at":null,"body":"Good progress is made on supporting the case of packages that carry their own typings in #2338.\r\n\r\nThat proposal doesn't currently deal with modules that do not carry their own typings, a.k.a. all modules that need typings from DefinitelyTyped.\r\n\r\nThis issue is to investigate possibilities of, and propose a (simple) solution for preventing problems when using (multiple versions of) external modules together.\r\n\r\n**TL;DR**\r\n\r\n1. No longer use `declare module \"...\" { }` in typings for external modules\r\n2. Add an extra step to the resolution logic of #2338 to look up this type of external typings\r\n\r\n\r\n**Example scenario**\r\n\r\n- myprogram\r\n  - mylib\r\n    - myutils@1.0\r\n  - myotherlib\r\n    - myutils@2.0\r\n\r\nSuppose that both `mylib` and `myotherlib` export a function, that returns a value of a type defined in `myutils`.\r\n\r\n**Existing scenario**\r\n\r\nLikely, both `mylib` and `myotherlib` will each have a `/// <reference path=\"./typings/tsd.d.ts\" />` line, which again has a `/// <reference path=\"./myutils/myutils.d.ts\" />` line.\r\n\r\n**Problem**\r\n\r\nBoth libs carry their own version of `myutils.d.ts`, which works fine as long as they are not used together.\r\n\r\nHowever, when they *are* used together (as in this example), all the `/// <reference ...>` lines will (need to) be 'merged', which essentially means the `declare module \"myutils\" { ... }` from both `mylib` and `myotherlib` will end up in the same 'global module name namespace'.\r\n\r\nThis gives a compiler error, and even if the compiler would somehow allow it, would make it impossible to refer to either version of `myutils`.\r\n\r\nAdditionally, tools like [`dts-generator`](https://github.com/SitePen/dts-generator) e.g. include the `/// <reference>` line inside of the `declare` blocks, which get ignored by the compiler. This leads to unknown-references when trying to use such a typing, and will typically be solved by adding e.g. a `myutils/myutils.d.ts` to `myprogram/typings/tsd.d.ts`, which will be wrong for one of the libs.\r\n\r\n**Solution**\r\n\r\nExternal modules have the nice property that there is no 'global namespace' (except the filesystem, maybe), and basically every reference is 'local'.\r\n\r\nIt makes sense to use the same referencing scheme that's used for resolving 'local' external modules (within a package) for 'normal' external modules (different npm packages).\r\n\r\nBasically, the idea consists of:\r\n- No longer using `declare module \"...\" { }` in typings for external modules (to prevent the global namespace clash)\r\n- Adding an extra step to the resolution logic of #2338 to look up this type of external typings (e.g. in `typings/` folder)\r\n\r\n**Advantages**\r\n\r\n- Multiple versions of a package can co-exist in the same program/library\r\n- `/// <reference>` lines are no longer needed in most cases (except probably for e.g. importing Mocha's `it()` and other 'true' globals)\r\n- One format to rule them all: external module typings are already generated without `declare module \"...\" { }` by `tsc`, so all 'sorts' of external module typings will look the same\r\n- Gradual upgrade path: the `tsd.d.ts`-way will still work for packages that do still use `declare module \"...\" { }` (although it will still have the name-clash problem etc.)\r\n\r\n**Disadvantages**\r\n\r\n- Typings on e.g. DefinitelyTyped will (gradually) need to be replaced with their non-wrapped version\r\n- Extra lookup step in the compiler\r\n- Location of these external typings (a.k.a. include path) needs to be configured somewhere and/or sensible default value chosen\r\n\r\n**Example 'new-style' typings**\r\n\r\nMost hand-crafted typings will typically look like:\r\n```ts\r\n/// myutils.d.ts\r\nexport interface BarType {\r\n    bar: number;\r\n}\r\nexport declare function something(): BarType;\r\n```\r\n\r\nBut just to make things more interesting, suppose the typings of `myutils` look like:\r\n```ts\r\n/// dist/bar.d.ts\r\nexport interface BarType {\r\n    bar: number;\r\n}\r\n\r\n/// dist/foo.d.ts\r\nimport bar = require(\"./bar\");\r\nexport declare function something(): bar.BarType;\r\n```\r\n\r\nNothing special here, this is what `tsc` generates today.\r\n(Note: dist/ may be because someone used CoffeeScript, not TypeScript, right? :))\r\n\r\nNow, the typings dir on e.g. DefinitelyTyped could look like:\r\n```\r\nDefinitelyTyped/myutils/latest/dist/bar.d.ts\r\nDefinitelyTyped/myutils/latest/dist/foo.d.ts\r\nDefinitelyTyped/myutils/1.0/dist/bar.d.ts\r\nDefinitelyTyped/myutils/1.0/dist/foo.d.ts\r\n```\r\n(Or maybe `2.0` instead of `latest`, ideas welcome.)\r\n\r\nAnd both `mylib` and `myotherlib` would have:\r\n```\r\ntypings/myutils/dist/bar.d.ts\r\ntypings/myutils/dist/foo.d.ts\r\n```\r\n\r\n**Looking up .d.ts**\r\n\r\nGiven e.g. `import { something } from \"myutils\"` the compiler could use [`myutils/package.json`'s `main` property](https://github.com/Microsoft/TypeScript/issues/2338#issuecomment-94555288) to get to `./dist/foo.js`, which in turn would resolve to `dist/foo.d.ts`.\r\n\r\nNice and simple: no need to have support from the authors of `myutils`, no `/// <reference>` lines.\r\nAnd it even supports the `import bar  = require(\"myutils/dist/bar\")` case.\r\n\r\n**Open questions**\r\n\r\n* Use one typings dir for both 'wrapped' and 'unwrapped' typings?\r\n* First do a lookup for external modules already `declare`'ed, e.g. through tsd.d.ts? If so, would probably make first bullet usable, nice for gradual upgrade path of DT typings.\r\n* Most DT typings will not want to mimic exact filesystem structure of package, using e.g. `myutils/latest/index.d.ts` will probably work out-of-the-box with external module resolution logic, but `myutils/latest/myutils.d.ts` or even `myutils/myutils.d.ts` may be easier for filename in editor tab?\r\n\r\nGood idea? Bad idea?"},"comment":{"url":"https://api.github.com/repos/Microsoft/TypeScript/issues/comments/94996554","html_url":"https://github.com/Microsoft/TypeScript/issues/2839#issuecomment-94996554","issue_url":"https://api.github.com/repos/Microsoft/TypeScript/issues/2839","id":94996554,"user":{"login":"mhfrantz","id":153273,"avatar_url":"https://avatars.githubusercontent.com/u/153273?v=3","gravatar_id":"","url":"https://api.github.com/users/mhfrantz","html_url":"https://github.com/mhfrantz","followers_url":"https://api.github.com/users/mhfrantz/followers","following_url":"https://api.github.com/users/mhfrantz/following{/other_user}","gists_url":"https://api.github.com/users/mhfrantz/gists{/gist_id}","starred_url":"https://api.github.com/users/mhfrantz/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mhfrantz/subscriptions","organizations_url":"https://api.github.com/users/mhfrantz/orgs","repos_url":"https://api.github.com/users/mhfrantz/repos","events_url":"https://api.github.com/users/mhfrantz/events{/privacy}","received_events_url":"https://api.github.com/users/mhfrantz/received_events","type":"User","site_admin":false},"created_at":"2015-04-22T01:54:30Z","updated_at":"2015-04-22T01:54:30Z","body":"Can you extend the example (which I think is a good idea) to cover the case where the types come from DefinitelyTyped that has not yet been modified as you suggest?\r\n\r\nOne of the \"features\" of DefinitelyTyped today is the ability to have a single d.ts file that contains the declarations for many modules.  The prime example is node.d.ts.  How would that be handled?\r\n\r\nNot all of the types are referenced with the appropriate module scoping.  For example, in bluebird.d.ts, you can reference it and thus gain access to the Promise class.  You can then use that type in your own d.ts file.  I suppose the \"right\" thing to do would be to require the Bluebird module to be imported, and then only refer to the Promise class via the imported name.\r\n\r\nI like the theory behind restructuring DefinitelyTyped as outlined here, but I wonder how long it would take to accomplish.  I sometimes wish for a parallel repository like npm where we can simply publish the d.ts files by claiming the namespace for individual modules, rather than centrally managing it like the DefinitelyTyped repo.\r\n\r\nAlternately, I want to be able to point to one or more alternate typings repos.  If your proposal would allow extensibility in the list of repos, then that would allow new-style repos to be developed piecemeal."}}