<h1 dir="auto">Introduction</h1>
<p dir="auto">Currently, type literals are capable of representing any instantiated (non-generic) type except those that are recursive.  This is because, as an anonymous type, they do not have a name with which to create this type.</p>
<p dir="auto">This proposal covers recursive type literals.  These type literals add the additional ability of the literal referring to itself.  This has one main advantage: emitting .d.ts files for expressions typed by class expressions now have a "flattened" representations.  As class expressions could easily have recursive components, we'd like to be able to emit a corresponding type representation into the .d.ts file without contaminating the namespace with additional fresh type names.</p>
<h1 dir="auto">Design</h1>
<div class="highlight highlight-source-ts notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="var x : &lt;Node&gt; { next: Node; value: number; };"><pre class="notranslate"><span class="pl-k">var</span> <span class="pl-s1">x</span> : <span class="pl-c1">&lt;</span><span class="pl-smi">Node</span><span class="pl-c1">&gt;</span> <span class="pl-kos">{</span> <span class="pl-c1">next</span>: <span class="pl-smi">Node</span><span class="pl-kos">;</span> <span class="pl-c1">value</span>: <span class="pl-smi">number</span><span class="pl-kos">;</span> <span class="pl-kos">}</span><span class="pl-kos">;</span></pre></div>
<p dir="auto">The above acts similarly to this example:</p>
<div class="highlight highlight-source-ts notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="interface Node { next: Node; value: number; };
var x : Node; "><pre class="notranslate"><span class="pl-k">interface</span> <span class="pl-smi">Node</span> <span class="pl-kos">{</span> <span class="pl-c1">next</span>: <span class="pl-smi">Node</span><span class="pl-kos">;</span> <span class="pl-c1">value</span>: <span class="pl-smi">number</span><span class="pl-kos">;</span> <span class="pl-kos">}</span><span class="pl-kos">;</span>
<span class="pl-k">var</span> <span class="pl-s1">x</span> : <span class="pl-smi">Node</span><span class="pl-kos">;</span> </pre></div>
<p dir="auto">with one critical exception: in the first example the 'Node' name is <strong>not</strong> visible outside of the type literal.</p>
<h1 dir="auto">Typechecking</h1>
<p dir="auto">Typechecking of recursive type literals works just as recursive interfaces, with the exception (as mentioned above) that the name given to the recursive type literal is not visible in the lexical scope outside of the type literal.  Otherwise, these expand and are compared for equality structurally just as interfaces.</p>
<h1 dir="auto">Differences with other designs</h1>
<p dir="auto">This design differs from similar designs, named the 'self' type design where there is a specific keywords that the type can refer to its self.  This proposal is strictly more expressive, albeit at the cost of some additional syntax.  For example, embedded recursive types are possible:</p>
<div class="highlight highlight-source-ts notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="var x: &lt;Node&gt; { up: &lt;Parent&gt;{ up: Parent; node: Node}; next: Node; value: number};"><pre class="notranslate"><span class="pl-k">var</span> <span class="pl-s1">x</span>: <span class="pl-c1">&lt;</span><span class="pl-smi">Node</span><span class="pl-c1">&gt;</span> <span class="pl-kos">{</span> <span class="pl-c1">up</span>: <span class="pl-c1">&lt;</span><span class="pl-smi">Parent</span><span class="pl-c1">&gt;</span><span class="pl-kos">{</span> <span class="pl-c1">up</span>: <span class="pl-smi">Parent</span><span class="pl-kos">;</span> <span class="pl-c1">node</span>: <span class="pl-smi">Node</span><span class="pl-kos">}</span><span class="pl-kos">;</span> <span class="pl-c1">next</span>: <span class="pl-smi">Node</span><span class="pl-kos">;</span> <span class="pl-c1">value</span>: <span class="pl-smi">number</span><span class="pl-kos">}</span><span class="pl-kos">;</span></pre></div>
<p dir="auto">Using the allowJs compiler option, if <a href="https://github.com/feross/buffer">buffer</a> or <a href="https://github.com/pillarjs/send">send</a> are dependencies, Duplicate identifier errors are reported:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="node_modules/buffer/index.js(94,5): error TS2300: Duplicate identifier 'length'.
node_modules/buffer/index.js(95,5): error TS2300: Duplicate identifier 'parent'.
node_modules/buffer/index.js(229,20): error TS2300: Duplicate identifier 'length'.
node_modules/buffer/index.js(230,20): error TS2300: Duplicate identifier 'parent'.
node_modules/send/index.js(203,22): error TS2300: Duplicate identifier 'root'.
node_modules/send/index.js(212,22): error TS2300: Duplicate identifier 'root'."><pre lang="log" class="notranslate"><code class="notranslate">node_modules/buffer/index.js(94,5): error TS2300: Duplicate identifier 'length'.
node_modules/buffer/index.js(95,5): error TS2300: Duplicate identifier 'parent'.
node_modules/buffer/index.js(229,20): error TS2300: Duplicate identifier 'length'.
node_modules/buffer/index.js(230,20): error TS2300: Duplicate identifier 'parent'.
node_modules/send/index.js(203,22): error TS2300: Duplicate identifier 'root'.
node_modules/send/index.js(212,22): error TS2300: Duplicate identifier 'root'.
</code></pre></div>
<p dir="auto">It seems similar to <a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="129199316" data-permission-text="Title is private" data-url="https://github.com/microsoft/TypeScript/issues/6645" data-hovercard-type="issue" data-hovercard-url="/microsoft/TypeScript/issues/6645/hovercard" href="https://github.com/microsoft/TypeScript/issues/6645">#6645</a>, but here in addition to this member assignment, prototypes are in play.</p>