<p dir="auto">The capability has been discussed <a href="http://stackoverflow.com/questions/29758765/json-to-typescript-class-instance" rel="nofollow">here</a> and <a href="http://stackoverflow.com/questions/22885995/how-do-i-initialize-a-typescript-object-with-a-json-object" rel="nofollow">here</a> and <a href="http://stackoverflow.com/questions/22875636/how-do-i-cast-a-json-object-to-a-typescript-class" rel="nofollow">here</a>.  I would like to see a built-in way of doing this in the Typescript language itself.  Sort of like a deserializer.</p>
<p dir="auto">JSON is the language of data.  Typescript will have greater adoption if there is an easy way to 'cast' a JSON string (or the javascript object created from it) into an instance of a Typescript class.  If it is just the javascript object, it doesn't have methods of the class and items initialized with the constructor.</p>
<p dir="auto">In the links above, one challenge is complex classes, ie: instance of Car class that has instance of Engine class in the same JSON.  There is not an elegant way of doing this.  The closest is to adopt a convention for metadata in the JSON which shows the subclass name.  For example, a property like <strong>name</strong> = "Engine", so the 'deserializer' knows what type of class to instantiate for the subclass items.  One suggestion to make the convention less arbitrary would be to use metadata that Typescript adds to the javascript when using Typescript's reflection.  If that was the approach, it would probably make sense to also create a 'serializer' that when stringifying the Typescript instance, also included the necessary metadata.</p>
<p dir="auto">Could there be a way to accomplish this with Typescript <a href="http://www.typescriptlang.org/Handbook#declaration-merging" rel="nofollow">declaration merging</a> or <a href="https://typescript.codeplex.com/wikipage?title=Mixins%20in%20TypeScript&amp;referringTitle=Declaration%20Merging" rel="nofollow">mixins</a>?</p>
<p dir="auto"><strong>Motivation</strong></p>
<p dir="auto">The shape of JSON stored in files can be validated using <a href="http://json-schema.org/" rel="nofollow">JSON schema</a>. However, JSON schema cannot be used to ensure the stored JSON corresponds to a specific TypeScript interface.</p>
<p dir="auto">Understandably, most JSON tends to be stored in databases. However, there are many cases where small documents are stored on the file system in order to permit quick editing. Two common examples are config and resource files. The JSON in these files is loaded at runtime and accessed by JavaScript code, thereby necessitating they correspond to specific TypeScript interfaces.</p>
<p dir="auto">We have a small but significant use case for this scenario.</p>
<p dir="auto"><strong>Proposal</strong></p>
<p dir="auto">Interface declarations file <code class="notranslate">user.d.ts</code></p>
<div class="highlight highlight-source-ts notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="declare module user {

     interface Address {
           house: number;
           street: string;
    }

    interface User  {
          name: string;
          address:Address;
          age: number;
    }
}"><pre class="notranslate"><span class="pl-k">declare</span> module <span class="pl-s1">user</span> <span class="pl-kos">{</span>

     <span class="pl-k">interface</span> <span class="pl-smi">Address</span> <span class="pl-kos">{</span>
           <span class="pl-c1">house</span>: <span class="pl-smi">number</span><span class="pl-kos">;</span>
           <span class="pl-c1">street</span>: <span class="pl-smi">string</span><span class="pl-kos">;</span>
    <span class="pl-kos">}</span>

    <span class="pl-k">interface</span> <span class="pl-smi">User</span>  <span class="pl-kos">{</span>
          <span class="pl-c1">name</span>: <span class="pl-smi">string</span><span class="pl-kos">;</span>
          <span class="pl-c1">address</span>:<span class="pl-smi">Address</span><span class="pl-kos">;</span>
          <span class="pl-c1">age</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">TypeScript JSON file <code class="notranslate">user.json.ts</code></p>
<div class="highlight highlight-source-ts notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="/// &lt;reference path=&quot;user.d.ts&quot; /&gt;
user.User: {            &lt;----------- Annotation
   &quot;name&quot;: &quot;Joe Bloggs&quot;, /*Comment*/    // Permit comments
   &quot;address&quot;: {
       &quot;house&quot;: &quot;1&quot;, // Error: Number expected
       street: &quot;London&quot;  // Error: Names must be quoted
    },
   &quot;age&quot;: 55     // Error: Missing comma
    &quot;id&quot;: 101 // Error: Invalid property
}"><pre class="notranslate"><span class="pl-c">/// &lt;reference path="user.d.ts" /&gt;</span>
<span class="pl-s1">user</span><span class="pl-kos">.</span><span class="pl-c1">User</span>: <span class="pl-kos">{</span>            <span class="pl-c1">&lt;</span><span class="pl-c1">--</span><span class="pl-c1">--</span><span class="pl-c1">--</span><span class="pl-c1">--</span><span class="pl-c1">--</span><span class="pl-c1">-</span> <span class="pl-smi">Annotation</span>
   <span class="pl-s">"name"</span>: <span class="pl-s">"Joe Bloggs"</span><span class="pl-kos">,</span> <span class="pl-c">/*Comment*/</span>    <span class="pl-c">// Permit comments</span>
   <span class="pl-s">"address"</span>: <span class="pl-kos">{</span>
       <span class="pl-s">"house"</span>: <span class="pl-s">"1"</span><span class="pl-kos">,</span> <span class="pl-c">// Error: Number expected</span>
       <span class="pl-c1">street</span>: <span class="pl-s">"London"</span>  <span class="pl-c">// Error: Names must be quoted</span>
    <span class="pl-kos">}</span><span class="pl-kos">,</span>
   <span class="pl-s">"age"</span>: <span class="pl-c1">55</span>     <span class="pl-c">// Error: Missing comma</span>
    <span class="pl-s">"id"</span>: <span class="pl-c1">101</span> <span class="pl-c">// Error: Invalid property</span>
<span class="pl-kos">}</span></pre></div>
<p dir="auto">Compiled output (after errors are corrected): File <code class="notranslate">user.json</code></p>
<div class="highlight highlight-source-ts notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="{
   &quot;name&quot;: &quot;Joe Bloggs&quot;,
   &quot;address&quot;: {
       &quot;house&quot;: 1
       &quot;street&quot;: &quot;London&quot;
    },
   &quot;age&quot;: 55    
}"><pre class="notranslate"><span class="pl-kos">{</span>
   <span class="pl-s">"name"</span>: <span class="pl-s">"Joe Bloggs"</span><span class="pl-kos">,</span>
   <span class="pl-s">"address"</span>: <span class="pl-kos">{</span>
       <span class="pl-s">"house"</span>: <span class="pl-c1">1</span>
       <span class="pl-s">"street"</span>: <span class="pl-s">"London"</span>
    <span class="pl-kos">}</span><span class="pl-kos">,</span>
   <span class="pl-s">"age"</span>: <span class="pl-c1">55</span>    
<span class="pl-kos">}</span></pre></div>