<p dir="auto"><strong>Update 5 November 2015</strong></p>
<p dir="auto">The functionality requested below is currently implemented in typescript since at least 1.8 with one main difference:</p>
<p dir="auto">Instead of having  <code class="notranslate">typescript.main</code> and  <code class="notranslate">typescript.definition</code> properties, there is only one  <code class="notranslate">typings</code> property which you can point to either a  <code class="notranslate">d.ts</code> file or a normal  <code class="notranslate">.ts</code> file.</p>
<p dir="auto">If you're developing a module to just use locally, you can have the  <code class="notranslate">typings</code> point to a  <code class="notranslate">.ts</code> file, but if you plan to publish the module, it is recommended to have it point to a  <code class="notranslate">d.ts</code> file. This is because you don't want your module consumers to recompile your module files, just consume its typings.</p>
<p dir="auto">I have setup an example of using this here:<br>
<a href="https://github.com/chanon/typescript_module_example">https://github.com/chanon/typescript_module_example</a></p>
<p dir="auto">There is a documentation page here that has more information:<br>
<a href="http://www.typescriptlang.org/docs/handbook/typings-for-npm-packages.html" rel="nofollow">http://www.typescriptlang.org/docs/handbook/typings-for-npm-packages.html</a></p>
<p dir="auto">Thank you TypeScript devs and all contributors.</p>
<p dir="auto"><strong>Original issue / feature request follows</strong></p>
<hr>
<h2 dir="auto">Motivation</h2>
<p dir="auto">In TypeScript it is a lot harder to re-use typescript modules compared to re-using npm modules in JavaScript.</p>
<p dir="auto">It would be beneficial if the typescript compiler is smart enough to look in node_modules folders and package.json files.</p>
<p dir="auto">The reason is so that npm module developers that use TypeScript might be able to start writing and distributing modules through npm itself. TypeScript would be able to piggyback on npm's infrastructure and wide support.</p>
<h2 dir="auto">Example for node_modules</h2>
<p dir="auto">If we had:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="./node_modules/concator/index.ts
./myApp.ts"><pre class="notranslate"><code class="notranslate">./node_modules/concator/index.ts
./myApp.ts
</code></pre></div>
<p dir="auto">And in index.ts we had:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="export function concat(param1: string, param2:string): string {
      return param1 + ' ' + param2;
}"><pre class="notranslate"><code class="notranslate">export function concat(param1: string, param2:string): string {
      return param1 + ' ' + param2;
}
</code></pre></div>
<p dir="auto">in myApp.ts:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="import concator = require('concator');  // loads the module from node_modules
var result = concator.concat('I like', 'this.');
var wontWork = concator.concat('this will fail');  // compile error, concat needs 2 params"><pre class="notranslate"><code class="notranslate">import concator = require('concator');  // loads the module from node_modules
var result = concator.concat('I like', 'this.');
var wontWork = concator.concat('this will fail');  // compile error, concat needs 2 params
</code></pre></div>
<p dir="auto">So basically, the compiler is smart enough to find the module in node_modules and it automatically uses the typescript version (index.ts).</p>
<p dir="auto">Then when the code is compiled to JavaScript, it naturally uses the JavaScript version.</p>
<h2 dir="auto">Importing Folders as Modules</h2>
<p dir="auto">A more basic case is supporting Node.js's popular rule of <a href="http://nodejs.org/api/modules.html#modules_folders_as_modules" rel="nofollow">http://nodejs.org/api/modules.html#modules_folders_as_modules</a> as suggested by <a class="user-mention notranslate" data-hovercard-type="user" data-hovercard-url="/users/vvakame/hovercard" data-octo-click="hovercard-link-click" data-octo-dimensions="link_type:self" href="https://github.com/vvakame">@vvakame</a> below and in the closed (semi-duplicate) <a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="38476667" data-permission-text="Title is private" data-url="https://github.com/microsoft/TypeScript/issues/207" data-hovercard-type="issue" data-hovercard-url="/microsoft/TypeScript/issues/207/hovercard" href="https://github.com/microsoft/TypeScript/issues/207">#207</a> issue.</p>
<h2 dir="auto">typescript.main in package.json</h2>
<p dir="auto">There could be an addition to package.json files to specify where the main .ts file of a TypeScript npm module is. This would be similar to the <code class="notranslate">main</code> key that specifies where the main JavaScript / .js file is but for TypeScript instead.</p>
<p dir="auto">Eg package.json for an npm module named "myModule" located at <code class="notranslate">node_modules/myModule/package.json</code></p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="{
     &quot;main&quot;: &quot;./dist/index.js&quot;,
     &quot;typescript&quot;: {
          &quot;main&quot;: &quot;./src/index.ts&quot;
     }
}"><pre class="notranslate"><code class="notranslate">{
     "main": "./dist/index.js",
     "typescript": {
          "main": "./src/index.ts"
     }
}
</code></pre></div>
<p dir="auto">In this example <code class="notranslate">node_modules/myModule/src/index.ts</code> would be the main TypeScript file and doing an <code class="notranslate">import myModule = require("myModule");</code> would import the <code class="notranslate">node_modules/myModule/src/index.ts</code> file.</p>
<p dir="auto">For a JavaScript coder writing <code class="notranslate">var myModule = require("myModule");</code> in a JavaScript file, the require would load the <code class="notranslate">node_modules/myModule/dist/index.js</code> file as usual.</p>
<p dir="auto">As can be seen in this example, the TypeScript src is in the <code class="notranslate">node_modules/module-name/src</code> folder and the compiled JS files would be in <code class="notranslate">node_modules/module-name/dist</code>.</p>
<p dir="auto">Something like this could be a (semi) standard for TypeScript npm modules so that the TypeScript source is cleanly separated from the compiled JavaScript output.</p>
<p dir="auto">A more basic case as suggested by <a class="user-mention notranslate" data-hovercard-type="user" data-hovercard-url="/users/vvakame/hovercard" data-octo-click="hovercard-link-click" data-octo-dimensions="link_type:self" href="https://github.com/vvakame">@vvakame</a> below is supporting the popular Node.js rule of <a href="http://nodejs.org/api/modules.html#modules_folders_as_module" rel="nofollow">http://nodejs.org/api/modules.html#modules_folders_as_module</a></p>
<h2 dir="auto">typescript.definition in package.json</h2>
<p dir="auto">Another possible key for package.json for non-TypeScript (plain JavaScript) npm modules could be <code class="notranslate">typescript.definition</code>. This would point to a .d.ts file that defines the module for TypeScript users of the npm module.</p>
<p dir="auto">So that an<br>
<code class="notranslate">import $ = require('jquery');</code><br>
would automatically read a <code class="notranslate">jquery.d.ts</code> file defined in the <code class="notranslate">typescript.definition</code> key in jQuery's package.json and make <code class="notranslate">$</code> the correct type.</p>
<p dir="auto">Example format:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="{
     &quot;main&quot;: &quot;./dist/index.js&quot;,
     &quot;typescript&quot;: {
          &quot;definition&quot;: &quot;./index.d.ts&quot;
     }
}"><pre class="notranslate"><code class="notranslate">{
     "main": "./dist/index.js",
     "typescript": {
          "definition": "./index.d.ts"
     }
}
</code></pre></div>
<p dir="auto">(This format is already used by tsd as <a class="user-mention notranslate" data-hovercard-type="user" data-hovercard-url="/users/Bartvds/hovercard" data-octo-click="hovercard-link-click" data-octo-dimensions="link_type:self" href="https://github.com/Bartvds">@Bartvds</a> explains below.)</p>
<p dir="auto">Then us TypeScript coders would just have to try to get as many non-TypeScript npm module maintainers to merge our pull requests that have our .d.ts files and package.json <code class="notranslate">typescript.definition</code> keys.</p>
<p dir="auto">If we succeed with that, then TypeScript coders' life would be bliss ... no more separate managing of DefinitelyTyped .d.ts files. Just npm install and you get your TypeScript definitions too! Automatically and up-to-date with the module version installed.</p>
<h2 dir="auto">List of Benefits</h2>
<p dir="auto">What we get from all of this is</p>
<ul dir="auto">
<li>npm modules can be written in TypeScript.</li>
<li>Both TypeScript and JavaScript coders can use these modules</li>
<li>The module users who use TypeScript get the benefits of static typing without the module coder (or user) having to use the usual method of writing (or generating) separate .d.ts files (so when the sourcecode of the module is already in TypeScript we don't have to have another .d.ts file to maintain)</li>
<li>There would be a way to easily re-use and distribute TypeScript modules using npm which everyone is already familiar with</li>
<li>It could help promote TypeScript usage itself, as JavaScript coders who use the npm modules written in TypeScript might see how nice / better the TypeScript source is and try switching to it. Or they might want to contribute to the module and since the source is in TypeScript they would have to learn it which may lead to them liking it and deciding to use it in their own projects.</li>
<li>Basically it would help grow the TypeScript community through all the code sharing that could result. Right now everyone's TypeScript code is mostly their own / in their own silo. This is actually probably an extremely important thing as not having a proper/easy way to share/distribute/re-use modules is probably limiting the growth of the language. [1]</li>
<li>Re-use of modules in internal projects would be a lot less of a hassle and would reduce the need for all those relative paths to .d.ts files and relative paths in module requires, and general .d.ts stuff. (Right now when writing TypeScript code, I find I have to learn to be good with counting ../../ s)</li>
<li>This approach also supports Browserify/Webpack as Browserify/Webpack also look under node_modules, so this allows for easy reusable / npm distributed TypeScript modules for both the server and browser</li>
<li>Non-TypeScript npm modules can easily be used in TypeScript with type information through the <code class="notranslate">typescript.definition</code> key addition. This allows .d.ts definition files to be packaged together with the npm module so that updating an npm module will automatically update its .d.ts definition file. This removes the need to update .d.ts files manually.</li>
<li>Using definition files through the <code class="notranslate">typescript.definition</code> is simpler because it is simply an <code class="notranslate">import moduleName = require("moduleName")</code> statement with no need for a separate <code class="notranslate">///&lt;reference ...</code></li>
<li>Using definition files through the <code class="notranslate">typescript.definition</code> should also allow the use of different versions of the module in the same code base without type names clashing.</li>
</ul>
<h2 dir="auto">Detailed Proposal</h2>
<p dir="auto"><a class="user-mention notranslate" data-hovercard-type="user" data-hovercard-url="/users/Nemo157/hovercard" data-octo-click="hovercard-link-click" data-octo-dimensions="link_type:self" href="https://github.com/Nemo157">@Nemo157</a> has written a very detailed proposal for how all of this should work at:</p>
<p dir="auto"><strong>Proposed TypeScript Require Resolution Semantics</strong><br>
<a href="https://gist.github.com/Nemo157/f20064a282ee620f3877">https://gist.github.com/Nemo157/f20064a282ee620f3877</a></p>
<p dir="auto">An addition in the proposal is the usage of <code class="notranslate">/typings</code> folders which can hold definition files that can be automatically managed by tools such as <code class="notranslate">tsd</code> for JavaScript npm modules that won't include definition files in their repositories.</p>
<h2 dir="auto">Final Supporting Facts</h2>
<p dir="auto">Since TypeScript compiles to JavaScript which runs mainly in two places: node.js and in browsers, supporting node_modules is beneficial to both places (practically all of where TypeScript is used) because of npm and Browserify/Webpack.</p>
<p dir="auto">ie. there is no reason to come up with a different scheme when node_modules is what all TypeScript users use already for maybe 75%-100% of all their JavaScript code. (Taking out 25% for maybe RequireJS users.)</p>
<h3 dir="auto">Footnotes</h3>
<p dir="auto">[1] -  BTW I see there is a NuGet package manager (?) from Microsoft that can distribute typescript modules (?), but coming from a node.js focused (non .NET focused) background, I don't see NuGet becoming widely used outside of Microsoft focused shops, especially as npm is <em>the</em> standard for node.js and is a leading standard for client side JavaScript too. If I didn't use TypeScript I would have never heard of NuGet. The average node.js / client side JavaScript coder would probably prefer using npm, the same tool they use already rather than having to use something Microsoft specific such as NuGet. (I don't actually know a thing about NuGet so what I'm saying here might not actually matter.)</p>
<p dir="auto">Sometimes we need to capture a union of types that may be a mixture of primitives, functions, objects, etc. but we want to leave it parameterised (just as we already can with interfaces).</p>
<h2 dir="auto">Example</h2>
<p dir="auto">A simple non-recursive example:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="type Source&lt;T&gt; = T | (() =&gt; T);"><pre class="notranslate"><code class="notranslate">type Source&lt;T&gt; = T | (() =&gt; T);
</code></pre></div>
<p dir="auto">Here, a source can either be a plain value or a nullary function that obtains a value.</p>
<p dir="auto">We can provide uniform access to such sources:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="function unwrap&lt;T&gt;(p: Source&lt;T&gt;) {
    return (typeof p === &quot;function&quot;) ? p() : p;
}"><pre class="notranslate"><code class="notranslate">function unwrap&lt;T&gt;(p: Source&lt;T&gt;) {
    return (typeof p === "function") ? p() : p;
}
</code></pre></div>
<p dir="auto">And then we can specify model interfaces where we we leave open the nature of the source but we tie down the value types:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="interface Person {
    name: Source&lt;string&gt;;
    age: Source&lt;number&gt;;
}"><pre class="notranslate"><code class="notranslate">interface Person {
    name: Source&lt;string&gt;;
    age: Source&lt;number&gt;;
}
</code></pre></div>
<p dir="auto">e.g. <code class="notranslate">name</code> is a constant, but <code class="notranslate">age</code> depends on when you ask:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="var p: Person = {
    name: &quot;John Lennon&quot;,
    age: () =&gt; ageFromDOB(1940, 10, 9),
}"><pre class="notranslate"><code class="notranslate">var p: Person = {
    name: "John Lennon",
    age: () =&gt; ageFromDOB(1940, 10, 9),
}
</code></pre></div>
<p dir="auto">But we can treat them identically in consuming code:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="var n = unwrap(p.name), a = unwrap(p.age);"><pre class="notranslate"><code class="notranslate">var n = unwrap(p.name), a = unwrap(p.age);
</code></pre></div>
<p dir="auto">NB. The above is already possible with union types alone, but the interface <code class="notranslate">Person</code> has to repeat the pattern:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="interface Person {
    name: string | (() =&gt; string);
    age: number | (() =&gt; number);
}"><pre class="notranslate"><code class="notranslate">interface Person {
    name: string | (() =&gt; string);
    age: number | (() =&gt; number);
}
</code></pre></div>
<p dir="auto">Not so bad for a simple example, but the pattern for a value source might evolve to get more complex and then you have a lot of fiddly updating to do because you "Did Repeat Yourself".</p>
<h2 dir="auto">Recursion</h2>
<p dir="auto">The more flexible recursive version:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="type Source&lt;T&gt; = T | (() =&gt; Source&lt;T&gt;);"><pre class="notranslate"><code class="notranslate">type Source&lt;T&gt; = T | (() =&gt; Source&lt;T&gt;);
</code></pre></div>
<p dir="auto">A source can either be a plain value or a nullary function that obtains a source (which may be a plain value terminating recursion, or a nullary function that... and so on).</p>
<p dir="auto">We can again provide uniform access to such sources, either with runtime recursion (risky until tail-call optimisation is widespread):</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="function unwrap&lt;T&gt;(p: Source&lt;T&gt;) {
    return (typeof p === &quot;function&quot;) ? unwrap(p()) : p;
}"><pre class="notranslate"><code class="notranslate">function unwrap&lt;T&gt;(p: Source&lt;T&gt;) {
    return (typeof p === "function") ? unwrap(p()) : p;
}
</code></pre></div>
<p dir="auto">Or with a loop:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="function unwrap&lt;T&gt;(p: Source&lt;T&gt;) {
    for (;;) {
        if (typeof p !== &quot;function&quot;) {
            return p;
        }
        p = p();
    }
}"><pre class="notranslate"><code class="notranslate">function unwrap&lt;T&gt;(p: Source&lt;T&gt;) {
    for (;;) {
        if (typeof p !== "function") {
            return p;
        }
        p = p();
    }
}
</code></pre></div>