<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Project Rinjani</title>
    <description>The latest articles on DEV Community by Project Rinjani (@bitrinjani).</description>
    <link>https://dev.to/bitrinjani</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F50295%2F16b1692e-a484-48e2-9524-8ee219e5978f.png</url>
      <title>DEV Community: Project Rinjani</title>
      <link>https://dev.to/bitrinjani</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/bitrinjani"/>
    <language>en</language>
    <item>
      <title>Why are those web services sending "Number" with double-quotes in JSON?  Castable library can handle them.</title>
      <dc:creator>Project Rinjani</dc:creator>
      <pubDate>Thu, 21 Dec 2017 10:23:25 +0000</pubDate>
      <link>https://dev.to/bitrinjani/why-are-those-web-services-sending-number-with-double-quotes-in-json--castable-library-can-handle-them-24f8</link>
      <guid>https://dev.to/bitrinjani/why-are-those-web-services-sending-number-with-double-quotes-in-json--castable-library-can-handle-them-24f8</guid>
      <description>&lt;h1&gt;
  
  
  Castable TypeScript Library
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://github.com/bitrinjani/castable"&gt;Castable&lt;/a&gt; sanitizes dirty external data by casting all properties at runtime to the types specified at compile time.&lt;/p&gt;

&lt;h1&gt;
  
  
  Why do you need this library?
&lt;/h1&gt;

&lt;p&gt;A lot of web services return &lt;code&gt;number&lt;/code&gt; type fields &lt;strong&gt;with double-quotes&lt;/strong&gt; in JSON. If you convert them by JSON.stringify, the double-quoted numbers will become &lt;code&gt;string&lt;/code&gt; type!!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;serverResponse&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`{
　　"name": "Milk", 
　　"price": "200", 
　　"tax": "10", 
}`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;product&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;serverResponse&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;sum&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;product&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;price&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;product&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;tax&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`sum: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// "200" + "10" = "20010"⛔️&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;TypeScript type annotation can help it? No, TypeScript cannot check such runtime type mismatch. You will get the same result even type annotation is perfect.&lt;/p&gt;

&lt;p&gt;That's why I've made this library. Castable can convert those types at runtime. All fields will be converted to the annotated types.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;cast&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Castable&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;castable&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nx"&gt;Product&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nx"&gt;Castable&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; 
  &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;cast&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;cast&lt;/span&gt; &lt;span class="nx"&gt;price&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;cast&lt;/span&gt; &lt;span class="nx"&gt;tax&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;serverResponse&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`{"name": "Milk", "price": "200", "tax": "10"}`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;product&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Product&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;serverResponse&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;sum&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;product&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;price&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;product&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;tax&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`sum: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// 200 + 10 = 210👍&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Castable internally applies Number("200") for price field and Number("10") for tax field in order to cast them to the correct type, recognizing those are actually &lt;code&gt;number&lt;/code&gt; type, not &lt;code&gt;string&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Supported types:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;number: "100" will be converted to real number &lt;code&gt;100&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;boolean: string "true", "false" in JSON will be real boolean &lt;code&gt;true&lt;/code&gt;, &lt;code&gt;false&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Date: Any string representation supported by Date constructor, like "Thu Dec 21 2017 18:38:58 GMT+0900 (Tokyo Standard Time)"&lt;/li&gt;
&lt;li&gt;Nested type&lt;/li&gt;
&lt;li&gt;Array&lt;/li&gt;
&lt;li&gt;Multi-dementional Array &lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Install
&lt;/h1&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; @bitr/castable
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Usage
&lt;/h1&gt;

&lt;ol&gt;
&lt;li&gt;Extend Castable&lt;/li&gt;
&lt;li&gt;Add &lt;code&gt;@cast&lt;/code&gt; decorator to primitive type field (string, number, boolean)&lt;/li&gt;
&lt;li&gt;Add &lt;code&gt;@cast(Date)&lt;/code&gt; decorator to Date type field&lt;/li&gt;
&lt;li&gt;Add &lt;code&gt;@cast @element(T)&lt;/code&gt; to Array type field&lt;/li&gt;
&lt;li&gt;Add &lt;code&gt;@cast&lt;/code&gt; decorator to nested type&lt;/li&gt;
&lt;li&gt;Do same to all nested types&lt;/li&gt;
&lt;/ol&gt;

&lt;h1&gt;
  
  
  Example
&lt;/h1&gt;

&lt;p&gt;This library is extensively used in &lt;a href="https://github.com/bitrinjani/r2"&gt;R2&lt;/a&gt;, e.g. &lt;a href="https://github.com/bitrinjani/r2/blob/master/src/Quoine/types.ts"&gt;type.ts&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>typescript</category>
      <category>javascript</category>
    </item>
  </channel>
</rss>
