<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>ts Archives - CodeJourney.net</title>
	<atom:link href="https://www.codejourney.net/tag/ts/feed/" rel="self" type="application/rss+xml" />
	<link>https://www.codejourney.net/tag/ts/</link>
	<description>Pragmatic full stack software development</description>
	<lastBuildDate>Sat, 29 Aug 2020 11:54:52 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.9.4</generator>

<image>
	<url>https://i0.wp.com/www.codejourney.net/wp-content/uploads/2018/10/cropped-512px-na-512px-JPEG-BEZ-NAPISU-1.jpg?fit=32%2C32&#038;ssl=1</url>
	<title>ts Archives - CodeJourney.net</title>
	<link>https://www.codejourney.net/tag/ts/</link>
	<width>32</width>
	<height>32</height>
</image> 
<site xmlns="com-wordpress:feed-additions:1">123174533</site>	<item>
		<title>Is It Worth Migrating to TypeScript?</title>
		<link>https://www.codejourney.net/is-it-worth-migrating-to-typescript/</link>
					<comments>https://www.codejourney.net/is-it-worth-migrating-to-typescript/#respond</comments>
		
		<dc:creator><![CDATA[Dawid Sibiński]]></dc:creator>
		<pubDate>Sat, 29 Aug 2020 11:03:05 +0000</pubDate>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[ts]]></category>
		<category><![CDATA[typescript]]></category>
		<category><![CDATA[typescript migration]]></category>
		<guid isPermaLink="false">https://www.codejourney.net/?p=3840</guid>

					<description><![CDATA[<p>Choosing migration strategy Bright side of migrating to TypeScript If you are a JavaScript developer, the best advice I can give you is to start using TypeScript 🙂 In this section I&#8217;m describing what positively surprised me since the beginning of starting to use TypeScript. Types &#8220;for free&#8221; As soon as we changed our transpiler&#8230;</p>
<p>The post <a href="https://www.codejourney.net/is-it-worth-migrating-to-typescript/">Is It Worth Migrating to TypeScript?</a> appeared first on <a href="https://www.codejourney.net">CodeJourney.net</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>For the past year I&#8217;ve been working on a JavaScript project for my client. We have a mid-size web application. We use React as the web development framework. Few months ago we decided to start migrating to TypeScript.</p>
<p>Today I can say that <strong>it was the best decision we could make</strong>. TypeScript makes working with JavaScript, which is sometimes <a href="https://www.codejourney.net/2018/11/10-most-shocking-javascript-features-for-csharp-developers/" target="_blank" rel="noopener noreferrer">surprising and quite hard to understand</a>, so much better experience. However, there were some challenges on this journey. If you want to know what issues we met and how we solved them, but also what huge advantages TypeScript gave us &#8211; read on <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f609.png" alt="😉" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>
<p><em>I will not discuss TypeScript itself in this article. This is a pure recap of challenges and the experience I gained when migrating to TypeScript.</em></p>



<span id="more-3840"></span>



<h2 class="wp-block-heading">Choosing migration strategy</h2>



<p>Before starting migrating to TypeScript, we had to choose the best strategy for this process. There were two possibilities we considered: <strong>migrating the whole JavaScript codebase to TypeScript at once</strong> or <strong>switching to TypeScript compiler and migrating part-by-part</strong>.</p>
<p>For those who are not familiar with TypeScript &#8211; it is a superset of JavaScript which adds typing information to your JS code. It means that <strong>every JavaScript code is also a valid TypeScript code</strong>. When compiling TypeScript code, TS compiler removes the typing data and outputs readable, vanilla JavaScript code ready to be executed.</p>
<p>Migrating the whole codebase to TypeScript would mean to change all files extensions to TypeScript ones: <em>.js</em> to <em>.ts</em> and <em>.jsx</em> to <em>.tsx</em>. It would also mean that TypeScript compiler starts checking types in those files. This approach is doable, but &#8211; depending on the size of your project &#8211; can take a long time. During migration the code would be frozen until you fully migrate the project. Also, for TypeScript beginners, it could be a bit frustrating having to type everything at once or use some tricks to tell TypeScript to ignore checking types in many cases (because the type is not known at this stage, or we want to do it later etc.).</p>
<p>Because of that, <strong>we decided to migrate part-by-part, having JavaScript and TypeScript files at the same time</strong>. It is possible thanks to enabling <a href="https://www.typescriptlang.org/docs/handbook/compiler-options.html" target="_blank" rel="noopener noreferrer"><em>allowJs&nbsp;</em>TS compiler option</a>. It means that TypeScript will compile both TS and JS files. Such approach allows the coexistence of old JS code with the new TS parts. It also allows moving only chosen parts of the application to TypeScript at the beginning and come back to the others later.</p>
<p>In our web application the biggest JS files have few thousand lines of code. Some of this legacy code still didn&#8217;t use React, but <a href="https://backbonejs.org/" target="_blank" rel="noopener noreferrer">Backbone</a> as their framework. We didn&#8217;t want to touch these oldest files in the beginning. Instead, <strong>we moved few recently written functionalities to TypeScript straightaway and decided to implement everything new in TS as well</strong>.</p>



<h2 class="wp-block-heading">Bright side of migrating to TypeScript</h2>



<p>If you are a JavaScript developer, the best advice I can give you is to start using TypeScript <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f642.png" alt="🙂" class="wp-smiley" style="height: 1em; max-height: 1em;" /> In this section I&#8217;m describing what positively surprised me since the beginning of starting to use TypeScript.</p>



<h3 class="wp-block-heading">Types &#8220;for free&#8221;</h3>



<p>As soon as we changed our transpiler from <em>babel-loader</em> to <em>ts-loader, </em>I wanted to know how we can get typing information for already-installed npm packages. It turns out that <strong>for 98% of the packages we used there&#8217;s already a typing information available</strong> as a separate npm package. </p>



<p>In most cases if you have a npm package called <em>abc</em> there&#8217;s a typing package available called <em>@types/abc</em>. I explored our <em>package.json </em>and for each package listed there I just executed <em>npm install @types/package-name</em>. 2 or 3 older or not-so-popular packages didn&#8217;t have types definitions available, but for the rest we got types for free, without having to type anything ourselves. This was a first, very nice surprise <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f609.png" alt="😉" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>



<p>You can find more information about TypeScript types definition packages, as well as contribute one yourself, <a href="https://github.com/DefinitelyTyped/DefinitelyTyped" target="_blank" rel="noreferrer noopener">here</a>.</p>



<h3 class="wp-block-heading">All new code is typed</h3>



<p>As I wrote before, every new feature we&#8217;ve added since the migration is written in TypeScript. Thanks to that, <strong>all n</strong>ew code we write <strong>is strongly typed</strong>. What&#8217;s remarkable here is that it required almost no effort. We just switched the compiler to TS (with a small struggle with webpack configuration, about which you can read below) and suddenly got into typed world for every new feature we implement. Quite impressive, isn&#8217;t it? <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f609.png" alt="😉" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>



<h3 class="wp-block-heading">JS-TS friendship</h3>



<p>Coexistence and friendship between JavaScript and TypeScript is HUGE. <strong>These two creatures are not enemies &#8211; they are best friends</strong> <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f60e.png" alt="😎" class="wp-smiley" style="height: 1em; max-height: 1em;" /> We&#8217;ve already gone through many scenarios when we needed to use something written in TS in a JS file and otherwise. It turns out that all of these scenarios are manageable. Sometimes you need to import something differently (for example using <em>require</em> instead of <em>import</em>), but it&#8217;s all possible. We found it super easy to write new features or even add parts of new features to already-existing JS code, writing everything in TypeScript.</p>



<p>We also rewrote some JS files that were used from multiple places in the app to TypeScript. As an example of JS-TS coexistence, I&#8217;m presenting below the potential <em>.ts</em> source code you might have. It contains both old, legacy JS code when we used <em>module.exports</em> and <em>prototype</em> to expose various services for data fetching, as well as a brand-new, nicely-exported TypeScript class:</p>



<p><style>.gist table { margin-bottom: 0; }</style><div style="tab-size: 8" id="gist105109386" class="gist">
    <div class="gist-file" translate="no" data-color-mode="light" data-light-theme="light">
      <div class="gist-data">
        
<div class="js-gist-file-update-container js-task-list-container">
      <div id="file-services-ts" class="file my-2">
    
    <div itemprop="text"
      class="Box-body p-0 blob-wrapper data type-typescript  "
      style="overflow: auto" tabindex="0" role="region"
      aria-label="services.ts content, created by dsibinski on 08:09AM on August 29, 2020."
    >

        
<div class="js-check-hidden-unicode js-blob-code-container blob-code-content">

  <template class="js-file-alert-template">
  <div data-view-component="true" class="flash flash-warn flash-full d-flex flex-items-center">
  <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert">
    <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg>
    <span>
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      <a class="Link--inTextBlock" href="https://github.co/hiddenchars" target="_blank">Learn more about bidirectional Unicode characters</a>
    </span>


  <div data-view-component="true" class="flash-action">        <a href="{{ revealButtonHref }}" data-view-component="true" class="btn-sm btn">    Show hidden characters
</a>
</div>
</div></template>
<template class="js-line-alert-template">
  <span aria-label="This line has hidden Unicode characters" data-view-component="true" class="line-alert tooltipped tooltipped-e">
    <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert">
    <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg>
</span></template>

  <table data-hpc class="highlight tab-size js-file-line-container" data-tab-size="4" data-paste-markdown-skip data-tagsearch-path="services.ts">
        <tr>
          <td id="file-services-ts-L1" class="blob-num js-line-number js-blob-rnum" data-line-number="1"></td>
          <td id="file-services-ts-LC1" class="blob-code blob-code-inner js-file-line">module.exports.UsersService = function (url) {</td>
        </tr>
        <tr>
          <td id="file-services-ts-L2" class="blob-num js-line-number js-blob-rnum" data-line-number="2"></td>
          <td id="file-services-ts-LC2" class="blob-code blob-code-inner js-file-line">  // &#8230; UsersService init code &#8230;</td>
        </tr>
        <tr>
          <td id="file-services-ts-L3" class="blob-num js-line-number js-blob-rnum" data-line-number="3"></td>
          <td id="file-services-ts-LC3" class="blob-code blob-code-inner js-file-line">};</td>
        </tr>
        <tr>
          <td id="file-services-ts-L4" class="blob-num js-line-number js-blob-rnum" data-line-number="4"></td>
          <td id="file-services-ts-LC4" class="blob-code blob-code-inner js-file-line">
</td>
        </tr>
        <tr>
          <td id="file-services-ts-L5" class="blob-num js-line-number js-blob-rnum" data-line-number="5"></td>
          <td id="file-services-ts-LC5" class="blob-code blob-code-inner js-file-line">module.exports.UsersService.prototype.getUser = function (id) {</td>
        </tr>
        <tr>
          <td id="file-services-ts-L6" class="blob-num js-line-number js-blob-rnum" data-line-number="6"></td>
          <td id="file-services-ts-LC6" class="blob-code blob-code-inner js-file-line">  // &#8230; code to get active user by id &#8230;</td>
        </tr>
        <tr>
          <td id="file-services-ts-L7" class="blob-num js-line-number js-blob-rnum" data-line-number="7"></td>
          <td id="file-services-ts-LC7" class="blob-code blob-code-inner js-file-line">};</td>
        </tr>
        <tr>
          <td id="file-services-ts-L8" class="blob-num js-line-number js-blob-rnum" data-line-number="8"></td>
          <td id="file-services-ts-LC8" class="blob-code blob-code-inner js-file-line">
</td>
        </tr>
        <tr>
          <td id="file-services-ts-L9" class="blob-num js-line-number js-blob-rnum" data-line-number="9"></td>
          <td id="file-services-ts-LC9" class="blob-code blob-code-inner js-file-line">
</td>
        </tr>
        <tr>
          <td id="file-services-ts-L10" class="blob-num js-line-number js-blob-rnum" data-line-number="10"></td>
          <td id="file-services-ts-LC10" class="blob-code blob-code-inner js-file-line">export class NewUsersService {</td>
        </tr>
        <tr>
          <td id="file-services-ts-L11" class="blob-num js-line-number js-blob-rnum" data-line-number="11"></td>
          <td id="file-services-ts-LC11" class="blob-code blob-code-inner js-file-line">  url: string;</td>
        </tr>
        <tr>
          <td id="file-services-ts-L12" class="blob-num js-line-number js-blob-rnum" data-line-number="12"></td>
          <td id="file-services-ts-LC12" class="blob-code blob-code-inner js-file-line">
</td>
        </tr>
        <tr>
          <td id="file-services-ts-L13" class="blob-num js-line-number js-blob-rnum" data-line-number="13"></td>
          <td id="file-services-ts-LC13" class="blob-code blob-code-inner js-file-line">  constructor(url: string) {</td>
        </tr>
        <tr>
          <td id="file-services-ts-L14" class="blob-num js-line-number js-blob-rnum" data-line-number="14"></td>
          <td id="file-services-ts-LC14" class="blob-code blob-code-inner js-file-line">    // &#8230; NewUsersService init code &#8230;</td>
        </tr>
        <tr>
          <td id="file-services-ts-L15" class="blob-num js-line-number js-blob-rnum" data-line-number="15"></td>
          <td id="file-services-ts-LC15" class="blob-code blob-code-inner js-file-line">  }</td>
        </tr>
        <tr>
          <td id="file-services-ts-L16" class="blob-num js-line-number js-blob-rnum" data-line-number="16"></td>
          <td id="file-services-ts-LC16" class="blob-code blob-code-inner js-file-line">
</td>
        </tr>
        <tr>
          <td id="file-services-ts-L17" class="blob-num js-line-number js-blob-rnum" data-line-number="17"></td>
          <td id="file-services-ts-LC17" class="blob-code blob-code-inner js-file-line">  getUser(id: number): JQuery.Promise&lt;UserViewModel, any, any&gt; {</td>
        </tr>
        <tr>
          <td id="file-services-ts-L18" class="blob-num js-line-number js-blob-rnum" data-line-number="18"></td>
          <td id="file-services-ts-LC18" class="blob-code blob-code-inner js-file-line">    // &#8230; code to get active user by id &#8230;</td>
        </tr>
        <tr>
          <td id="file-services-ts-L19" class="blob-num js-line-number js-blob-rnum" data-line-number="19"></td>
          <td id="file-services-ts-LC19" class="blob-code blob-code-inner js-file-line">  }</td>
        </tr>
        <tr>
          <td id="file-services-ts-L20" class="blob-num js-line-number js-blob-rnum" data-line-number="20"></td>
          <td id="file-services-ts-LC20" class="blob-code blob-code-inner js-file-line">}</td>
        </tr>
  </table>
</div>


    </div>

  </div>

</div>

      </div>
      <div class="gist-meta">
        <a href="https://gist.github.com/dsibinski/fceb3650f2121640a5e32a78ec3dc740/raw/504b504a930a8262f334017f8aeddc675e3692bf/services.ts" style="float:right" class="Link--inTextBlock">view raw</a>
        <a href="https://gist.github.com/dsibinski/fceb3650f2121640a5e32a78ec3dc740#file-services-ts" class="Link--inTextBlock">
          services.ts
        </a>
        hosted with &#10084; by <a class="Link--inTextBlock" href="https://github.com">GitHub</a>
      </div>
    </div>
</div>
 </p>



<p>Such code can of course be in separate files, but it only shows how good TS and JS can coexist together. You can keep your old code working, while implementing anything new in TypeScript.</p>



<h3 class="wp-block-heading">Flexibility in partial migrating to TypeScript</h3>



<p>It turns out that choosing to partially move our web project to TypeScript was a great decision. The team wouldn&#8217;t be so happy and enthusiastic about TS if we told them to move legacy Backbone code to TypeScript. Instead, we gave them a nice tool which can be used for all new stuff. Also, if someone likes the idea and wants to move already-existing JS file to TS, he or she is welcome to do so. </p>



<p>That&#8217;s how <strong>we are still migrating our project to TypeScript, without any hustle and frustration</strong> <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f609.png" alt="😉" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>



<h3 class="wp-block-heading">Wisdom of TypeScript</h3>



<p>I&#8217;m positively surprised by TypeScript almost every day. At some point I get to the issue that seems hard to be solved or quite non-standard. Then I find a solution online and <strong>it makes me really impressed about the job <a href="https://github.com/microsoft/TypeScript" target="_blank" rel="noreferrer noopener">the community and Microsoft has been doing</a> around the language</strong>. </p>



<p>These are sometimes small, but smart things. Recently we got surprised by <a href="https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-1.html#keyof-and-lookup-types" target="_blank" rel="noreferrer noopener">keyof</a>, which lets you get names of the allowed properties of your type. Generally <a href="https://www.typescriptlang.org/docs/handbook/advanced-types.html" target="_blank" rel="noreferrer noopener">the typing system</a> is really advanced and impressive. For some it can be a disadvantage, but I think it gives an enormous flexibility. </p>



<p>This is somehow the JavaScript you-can-do-whatever-you-want philosophy smuggled into TypeScript <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f601.png" alt="😁" class="wp-smiley" style="height: 1em; max-height: 1em;" /> But in a much smarter way. I&#8217;m sure that when you start working with TypeScript you&#8217;ll get what I mean by its wisdom <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f642.png" alt="🙂" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>



<h3 class="wp-block-heading">Small effort, huge benefits</h3>



<p>Last, but not least, I must admit that <strong>migrating to TypeScript was quite an easy and smooth process. The value for the effort is huge</strong>. You get a typed world with very little work.</p>



<h2 class="wp-block-heading">Migrating to TypeScript struggles</h2>



<p>During the migration process we met few difficulties. Some of them we managed to solve fully or partially. If you have any better ideas on these things, feel free to let me know in the comments.</p>



<h3 class="wp-block-heading">Complexity of webpack configuration</h3>



<p>When switching to TypeScript we had few issues with <a href="https://webpack.js.org/" target="_blank" rel="noreferrer noopener">webpack</a> configuration. We have used <a href="https://github.com/babel/babel-loader" target="_blank" rel="noreferrer noopener"><em>babel-loader</em></a> before for transpiling JavaScript and initially we wanted to keep it in the TS compilation process. We first tried to keep <em>babel-loader</em> for JS(X) files and use <em>ts-loader</em> for TS(X) files, but it didn&#8217;t work &#8211; we were getting weird compilation errors. </p>



<p>Then we tried to compile everything using <em>ts-loader</em> and then recompile it again using <em>babel</em> to ensure (as we initially thought would be wise) backwards compatibility. We also couldn&#8217;t make it working.</p>



<p><strong>Finally, we decided to compile everything &#8211; both JavaScript and TypeScript files &#8211; using <em>ts-loader</em></strong> (including React files). It worked, except source code maps. When we tried to debug in Chrome console it seemed the source code is not refreshing properly after rebuilding. Breakpoints were often not hit and the debugging didn&#8217;t seem right. </p>



<p>After a bit of struggling we found a solution. We set <a href="https://webpack.js.org/configuration/devtool/" target="_blank" rel="noreferrer noopener">devtool</a> webpack option to <em>eval-source-map</em> and configured <em><a href="https://www.npmjs.com/package/source-map-loader" target="_blank" rel="noreferrer noopener">source-map-loader</a></em> for <em>.js</em> files. Finally, the proper part of webpack config looks as follows:</p>



<figure class="wp-block-embed is-type-rich is-provider-embed-handler"><div class="wp-block-embed__wrapper">
<style>.gist table { margin-bottom: 0; }</style><div style="tab-size: 8" id="gist105110022" class="gist">
    <div class="gist-file" translate="no" data-color-mode="light" data-light-theme="light">
      <div class="gist-data">
        
<div class="js-gist-file-update-container js-task-list-container">
      <div id="file-webpack_partial-config-js" class="file my-2">
    
    <div itemprop="text"
      class="Box-body p-0 blob-wrapper data type-javascript  "
      style="overflow: auto" tabindex="0" role="region"
      aria-label="webpack_partial.config.js content, created by dsibinski on 09:40AM on August 29, 2020."
    >

        
<div class="js-check-hidden-unicode js-blob-code-container blob-code-content">

  <template class="js-file-alert-template">
  <div data-view-component="true" class="flash flash-warn flash-full d-flex flex-items-center">
  <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert">
    <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg>
    <span>
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      <a class="Link--inTextBlock" href="https://github.co/hiddenchars" target="_blank">Learn more about bidirectional Unicode characters</a>
    </span>


  <div data-view-component="true" class="flash-action">        <a href="{{ revealButtonHref }}" data-view-component="true" class="btn-sm btn">    Show hidden characters
</a>
</div>
</div></template>
<template class="js-line-alert-template">
  <span aria-label="This line has hidden Unicode characters" data-view-component="true" class="line-alert tooltipped tooltipped-e">
    <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert">
    <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg>
</span></template>

  <table data-hpc class="highlight tab-size js-file-line-container" data-tab-size="4" data-paste-markdown-skip data-tagsearch-path="webpack_partial.config.js">
        <tr>
          <td id="file-webpack_partial-config-js-L1" class="blob-num js-line-number js-blob-rnum" data-line-number="1"></td>
          <td id="file-webpack_partial-config-js-LC1" class="blob-code blob-code-inner js-file-line">devtool: &quot;eval-source-map&quot;,</td>
        </tr>
        <tr>
          <td id="file-webpack_partial-config-js-L2" class="blob-num js-line-number js-blob-rnum" data-line-number="2"></td>
          <td id="file-webpack_partial-config-js-LC2" class="blob-code blob-code-inner js-file-line">module: {</td>
        </tr>
        <tr>
          <td id="file-webpack_partial-config-js-L3" class="blob-num js-line-number js-blob-rnum" data-line-number="3"></td>
          <td id="file-webpack_partial-config-js-LC3" class="blob-code blob-code-inner js-file-line">    rules: [</td>
        </tr>
        <tr>
          <td id="file-webpack_partial-config-js-L4" class="blob-num js-line-number js-blob-rnum" data-line-number="4"></td>
          <td id="file-webpack_partial-config-js-LC4" class="blob-code blob-code-inner js-file-line">        { </td>
        </tr>
        <tr>
          <td id="file-webpack_partial-config-js-L5" class="blob-num js-line-number js-blob-rnum" data-line-number="5"></td>
          <td id="file-webpack_partial-config-js-LC5" class="blob-code blob-code-inner js-file-line">            enforce: &quot;pre&quot;, </td>
        </tr>
        <tr>
          <td id="file-webpack_partial-config-js-L6" class="blob-num js-line-number js-blob-rnum" data-line-number="6"></td>
          <td id="file-webpack_partial-config-js-LC6" class="blob-code blob-code-inner js-file-line">            test: /\.js$/, </td>
        </tr>
        <tr>
          <td id="file-webpack_partial-config-js-L7" class="blob-num js-line-number js-blob-rnum" data-line-number="7"></td>
          <td id="file-webpack_partial-config-js-LC7" class="blob-code blob-code-inner js-file-line">            exclude: /node_modules/, </td>
        </tr>
        <tr>
          <td id="file-webpack_partial-config-js-L8" class="blob-num js-line-number js-blob-rnum" data-line-number="8"></td>
          <td id="file-webpack_partial-config-js-LC8" class="blob-code blob-code-inner js-file-line">            loader: &quot;source-map-loader&quot; </td>
        </tr>
        <tr>
          <td id="file-webpack_partial-config-js-L9" class="blob-num js-line-number js-blob-rnum" data-line-number="9"></td>
          <td id="file-webpack_partial-config-js-LC9" class="blob-code blob-code-inner js-file-line">        },</td>
        </tr>
        <tr>
          <td id="file-webpack_partial-config-js-L10" class="blob-num js-line-number js-blob-rnum" data-line-number="10"></td>
          <td id="file-webpack_partial-config-js-LC10" class="blob-code blob-code-inner js-file-line">        {</td>
        </tr>
        <tr>
          <td id="file-webpack_partial-config-js-L11" class="blob-num js-line-number js-blob-rnum" data-line-number="11"></td>
          <td id="file-webpack_partial-config-js-LC11" class="blob-code blob-code-inner js-file-line">            test: /\.(t|j)sx?$/,</td>
        </tr>
        <tr>
          <td id="file-webpack_partial-config-js-L12" class="blob-num js-line-number js-blob-rnum" data-line-number="12"></td>
          <td id="file-webpack_partial-config-js-LC12" class="blob-code blob-code-inner js-file-line">            exclude: /node_modules/,</td>
        </tr>
        <tr>
          <td id="file-webpack_partial-config-js-L13" class="blob-num js-line-number js-blob-rnum" data-line-number="13"></td>
          <td id="file-webpack_partial-config-js-LC13" class="blob-code blob-code-inner js-file-line">            use: { </td>
        </tr>
        <tr>
          <td id="file-webpack_partial-config-js-L14" class="blob-num js-line-number js-blob-rnum" data-line-number="14"></td>
          <td id="file-webpack_partial-config-js-LC14" class="blob-code blob-code-inner js-file-line">                loader: &#39;ts-loader&#39;</td>
        </tr>
        <tr>
          <td id="file-webpack_partial-config-js-L15" class="blob-num js-line-number js-blob-rnum" data-line-number="15"></td>
          <td id="file-webpack_partial-config-js-LC15" class="blob-code blob-code-inner js-file-line">            }</td>
        </tr>
        <tr>
          <td id="file-webpack_partial-config-js-L16" class="blob-num js-line-number js-blob-rnum" data-line-number="16"></td>
          <td id="file-webpack_partial-config-js-LC16" class="blob-code blob-code-inner js-file-line">        },  </td>
        </tr>
        <tr>
          <td id="file-webpack_partial-config-js-L17" class="blob-num js-line-number js-blob-rnum" data-line-number="17"></td>
          <td id="file-webpack_partial-config-js-LC17" class="blob-code blob-code-inner js-file-line">    ],</td>
        </tr>
        <tr>
          <td id="file-webpack_partial-config-js-L18" class="blob-num js-line-number js-blob-rnum" data-line-number="18"></td>
          <td id="file-webpack_partial-config-js-LC18" class="blob-code blob-code-inner js-file-line">},</td>
        </tr>
  </table>
</div>


    </div>

  </div>

</div>

      </div>
      <div class="gist-meta">
        <a href="https://gist.github.com/dsibinski/2cb3c4c10fe63a9020508c20fa31eef3/raw/6e5f9baf9bf87fec5c43cccf25e5610607c36fa6/webpack_partial.config.js" style="float:right" class="Link--inTextBlock">view raw</a>
        <a href="https://gist.github.com/dsibinski/2cb3c4c10fe63a9020508c20fa31eef3#file-webpack_partial-config-js" class="Link--inTextBlock">
          webpack_partial.config.js
        </a>
        hosted with &#10084; by <a class="Link--inTextBlock" href="https://github.com">GitHub</a>
      </div>
    </div>
</div>

</div></figure>



<p>So far we also haven&#8217;t noticed any issues related to backwards compatibility that were theoretically solved by <em>babel</em>. TypeScript compiler does its job very well.</p>



<h3 class="wp-block-heading">Complicated JS -&gt; TS refactoring</h3>



<p>I found out that JS to TS refactoring is not always an easy task. <strong>Some things that are allowed by JavaScript are not valid in TypeScript</strong>. In most cases it means that something was wrong with your JavaScript code, but we all know how it is with legacy code refactoring <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f609.png" alt="😉" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>



<p class="has-dark-gray-color has-text-color">As an example, we had several functions that we added to a <span style="color:#ef7604" class="tadv-color">String</span> prototype in JavaScript:</p>



<figure class="wp-block-embed is-type-rich is-provider-embed-handler"><div class="wp-block-embed__wrapper">
<style>.gist table { margin-bottom: 0; }</style><div style="tab-size: 8" id="gist105110060" class="gist">
    <div class="gist-file" translate="no" data-color-mode="light" data-light-theme="light">
      <div class="gist-data">
        
<div class="js-gist-file-update-container js-task-list-container">
      <div id="file-string_prototype_helpers-js" class="file my-2">
    
    <div itemprop="text"
      class="Box-body p-0 blob-wrapper data type-javascript  "
      style="overflow: auto" tabindex="0" role="region"
      aria-label="string_prototype_helpers.js content, created by dsibinski on 09:47AM on August 29, 2020."
    >

        
<div class="js-check-hidden-unicode js-blob-code-container blob-code-content">

  <template class="js-file-alert-template">
  <div data-view-component="true" class="flash flash-warn flash-full d-flex flex-items-center">
  <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert">
    <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg>
    <span>
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      <a class="Link--inTextBlock" href="https://github.co/hiddenchars" target="_blank">Learn more about bidirectional Unicode characters</a>
    </span>


  <div data-view-component="true" class="flash-action">        <a href="{{ revealButtonHref }}" data-view-component="true" class="btn-sm btn">    Show hidden characters
</a>
</div>
</div></template>
<template class="js-line-alert-template">
  <span aria-label="This line has hidden Unicode characters" data-view-component="true" class="line-alert tooltipped tooltipped-e">
    <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert">
    <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg>
</span></template>

  <table data-hpc class="highlight tab-size js-file-line-container" data-tab-size="4" data-paste-markdown-skip data-tagsearch-path="string_prototype_helpers.js">
        <tr>
          <td id="file-string_prototype_helpers-js-L1" class="blob-num js-line-number js-blob-rnum" data-line-number="1"></td>
          <td id="file-string_prototype_helpers-js-LC1" class="blob-code blob-code-inner js-file-line">String.prototype.contains = function (it) {</td>
        </tr>
        <tr>
          <td id="file-string_prototype_helpers-js-L2" class="blob-num js-line-number js-blob-rnum" data-line-number="2"></td>
          <td id="file-string_prototype_helpers-js-LC2" class="blob-code blob-code-inner js-file-line">        return this.indexOf(it) != -1;</td>
        </tr>
        <tr>
          <td id="file-string_prototype_helpers-js-L3" class="blob-num js-line-number js-blob-rnum" data-line-number="3"></td>
          <td id="file-string_prototype_helpers-js-LC3" class="blob-code blob-code-inner js-file-line">    };</td>
        </tr>
  </table>
</div>


    </div>

  </div>

</div>

      </div>
      <div class="gist-meta">
        <a href="https://gist.github.com/dsibinski/5e9553424d7441fddefee5f2519ad6dc/raw/d67095fec29dee3eda04be5994faa58f7f94cee7/string_prototype_helpers.js" style="float:right" class="Link--inTextBlock">view raw</a>
        <a href="https://gist.github.com/dsibinski/5e9553424d7441fddefee5f2519ad6dc#file-string_prototype_helpers-js" class="Link--inTextBlock">
          string_prototype_helpers.js
        </a>
        hosted with &#10084; by <a class="Link--inTextBlock" href="https://github.com">GitHub</a>
      </div>
    </div>
</div>

</div></figure>



<p>Such code becomes invalid in TypeScript:</p>



<figure class="wp-block-image size-large"><img data-recalc-dims="1" fetchpriority="high" decoding="async" width="782" height="174" data-attachment-id="3862" data-permalink="https://www.codejourney.net/is-it-worth-migrating-to-typescript/typescript_prototype_functions_error/" data-orig-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2020/08/TypeScript_prototype_functions_error.png?fit=782%2C174&amp;ssl=1" data-orig-size="782,174" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="TypeScript_prototype_functions_error" data-image-description="" data-image-caption="" data-large-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2020/08/TypeScript_prototype_functions_error.png?fit=782%2C174&amp;ssl=1" src="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2020/08/TypeScript_prototype_functions_error.png?resize=782%2C174&#038;ssl=1" alt="Migrating to TypeScript: TS error about non-existing function on String prototype in VS Code" class="wp-image-3862" srcset="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2020/08/TypeScript_prototype_functions_error.png?w=782&amp;ssl=1 782w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2020/08/TypeScript_prototype_functions_error.png?resize=300%2C67&amp;ssl=1 300w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2020/08/TypeScript_prototype_functions_error.png?resize=768%2C171&amp;ssl=1 768w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2020/08/TypeScript_prototype_functions_error.png?resize=676%2C150&amp;ssl=1 676w" sizes="(max-width: 782px) 100vw, 782px" /><figcaption>TypeScript complaining about non-existing function</figcaption></figure>



<p>A non-obvious solution to that issue is to extend <span style="color:#ef7604" class="tadv-color">String</span> interface by declaring typed functions you want to add:</p>



<figure class="wp-block-embed is-type-rich is-provider-embed-handler"><div class="wp-block-embed__wrapper">
<style>.gist table { margin-bottom: 0; }</style><div style="tab-size: 8" id="gist105110103" class="gist">
    <div class="gist-file" translate="no" data-color-mode="light" data-light-theme="light">
      <div class="gist-data">
        
<div class="js-gist-file-update-container js-task-list-container">
      <div id="file-string_prototype_helpers-ts" class="file my-2">
    
    <div itemprop="text"
      class="Box-body p-0 blob-wrapper data type-typescript  "
      style="overflow: auto" tabindex="0" role="region"
      aria-label="string_prototype_helpers.ts content, created by dsibinski on 09:53AM on August 29, 2020."
    >

        
<div class="js-check-hidden-unicode js-blob-code-container blob-code-content">

  <template class="js-file-alert-template">
  <div data-view-component="true" class="flash flash-warn flash-full d-flex flex-items-center">
  <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert">
    <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg>
    <span>
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      <a class="Link--inTextBlock" href="https://github.co/hiddenchars" target="_blank">Learn more about bidirectional Unicode characters</a>
    </span>


  <div data-view-component="true" class="flash-action">        <a href="{{ revealButtonHref }}" data-view-component="true" class="btn-sm btn">    Show hidden characters
</a>
</div>
</div></template>
<template class="js-line-alert-template">
  <span aria-label="This line has hidden Unicode characters" data-view-component="true" class="line-alert tooltipped tooltipped-e">
    <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert">
    <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg>
</span></template>

  <table data-hpc class="highlight tab-size js-file-line-container" data-tab-size="4" data-paste-markdown-skip data-tagsearch-path="string_prototype_helpers.ts">
        <tr>
          <td id="file-string_prototype_helpers-ts-L1" class="blob-num js-line-number js-blob-rnum" data-line-number="1"></td>
          <td id="file-string_prototype_helpers-ts-LC1" class="blob-code blob-code-inner js-file-line">interface String {</td>
        </tr>
        <tr>
          <td id="file-string_prototype_helpers-ts-L2" class="blob-num js-line-number js-blob-rnum" data-line-number="2"></td>
          <td id="file-string_prototype_helpers-ts-LC2" class="blob-code blob-code-inner js-file-line">    contains(this : string, it : any): boolean;</td>
        </tr>
        <tr>
          <td id="file-string_prototype_helpers-ts-L3" class="blob-num js-line-number js-blob-rnum" data-line-number="3"></td>
          <td id="file-string_prototype_helpers-ts-LC3" class="blob-code blob-code-inner js-file-line">}</td>
        </tr>
        <tr>
          <td id="file-string_prototype_helpers-ts-L4" class="blob-num js-line-number js-blob-rnum" data-line-number="4"></td>
          <td id="file-string_prototype_helpers-ts-LC4" class="blob-code blob-code-inner js-file-line">
</td>
        </tr>
        <tr>
          <td id="file-string_prototype_helpers-ts-L5" class="blob-num js-line-number js-blob-rnum" data-line-number="5"></td>
          <td id="file-string_prototype_helpers-ts-LC5" class="blob-code blob-code-inner js-file-line">String.prototype.contains = function (it) {</td>
        </tr>
        <tr>
          <td id="file-string_prototype_helpers-ts-L6" class="blob-num js-line-number js-blob-rnum" data-line-number="6"></td>
          <td id="file-string_prototype_helpers-ts-LC6" class="blob-code blob-code-inner js-file-line">    return this.indexOf(it) != -1;</td>
        </tr>
        <tr>
          <td id="file-string_prototype_helpers-ts-L7" class="blob-num js-line-number js-blob-rnum" data-line-number="7"></td>
          <td id="file-string_prototype_helpers-ts-LC7" class="blob-code blob-code-inner js-file-line">};</td>
        </tr>
  </table>
</div>


    </div>

  </div>

</div>

      </div>
      <div class="gist-meta">
        <a href="https://gist.github.com/dsibinski/f0cd64ae8967aee9a0cfc13409259e1f/raw/92dd7b6a53393c445096b7b63ba08149acf256c5/string_prototype_helpers.ts" style="float:right" class="Link--inTextBlock">view raw</a>
        <a href="https://gist.github.com/dsibinski/f0cd64ae8967aee9a0cfc13409259e1f#file-string_prototype_helpers-ts" class="Link--inTextBlock">
          string_prototype_helpers.ts
        </a>
        hosted with &#10084; by <a class="Link--inTextBlock" href="https://github.com">GitHub</a>
      </div>
    </div>
</div>

</div></figure>



<p>There are more subtle difficulties like that you can meet while migrating JS code to TypeScript. However, in the end it gives you a possibility to make your codebase better.</p>



<h3 class="wp-block-heading">Keeping view models in sync</h3>



<p>An issue I didn&#8217;t think about before migrating to TypeScript was a need to keep frontend and backend view models in sync.</p>



<p>One of the first things you&#8217;d like to have in your TypeScript codebase is to have as much typed data as possible. We use .NET and C# as the backend of our application. ASP.NET MVC controllers returned the strongly-typed objects into the previously chaotic and untyped JS world. Now we are strongly-typed with TypeScript, so we&#8217;d like all this data typed as well <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f60e.png" alt="😎" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>



<p>Here comes the problem. First of all <strong>our C# data models which we returned from the controllers were not the best</strong>. In most cases we returned a DTO object which contained many properties from which only few were used by JavaScript code. We never saw this problem, because in JS we just dynamically typed properties names we wanted to use. We didn&#8217;t see how much of not needed data is sent from ASP controllers to the web browser.</p>



<p>Now <strong>with TypeScript we needed to create these objects definitions also in TypeScript</strong>. Having a huge DTO object returned from the controller, with another X objects on which this DTO depends, it was a nightmare. <strong>It turned out that for a single DTO I had to create 10-15 TypeScript objects just to use 5-10 properties in the frontend code!</strong></p>



<p>That&#8217;s the moment when we came to the necessity of <strong>creating web view models</strong>. The idea is to <strong>return a view model from a controller, not the whole DTO object. This view model contains only the data which is needed by TypeScript (frontend)</strong>.</p>



<p>I think this is nothing new for experienced web developers. However, now comes the question: <strong>how do we keep backend (C#) view models in sync with frontend (TypeScript) ones?</strong></p>



<p>Unfortunately, I haven&#8217;t found a perfect solution for that. The best method I came up with is&#8230; <strong>manually keeping these view models in sync</strong>. </p>



<p>There&#8217;s a <a href="https://marketplace.visualstudio.com/items?itemName=adrianwilczynski.csharp-to-typescript" target="_blank" rel="noreferrer noopener">C# to TypeScript</a> VS Code extension which allows to paste the copied C# code as its TypeScript equivalent. It makes the job a bit easier. It even has a <a href="https://www.nuget.org/packages/CSharpToTypeScript.CLITool/" target="_blank" rel="noreferrer noopener">CLI tool</a>, but it produces a single <em>.ts</em> file from a single <em>.cs</em> file. If you have multiple objects in a single C# file it will produce a single TypeScript file with all these objects. If any of those objects is used in other files (unfortunately we have many of such cases), these dependencies will not be automatically added as imports in the auto-generated <em>.ts</em> files.</p>



<p>However, I don&#8217;t find it very problematic for now. As soon as the TS view models are created, we just need to update them as often as we update C# view models. I think this is a very common issue so if you know any better solution here &#8211; please share in the comments <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f609.png" alt="😉" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>



<h2 class="wp-block-heading">Migrating to TypeScript &#8211; summary</h2>



<p>Migrating to TypeScript has been a very interesting and rewarding process. Compared to vanilla JavaScript, TypeScript lets programmers see many problems. This allows to see how bad our codebase was. We even realized that our server-side C# code was not the best (see the section about view models above). Thanks to introducing TypeScript we improved a lot of our JavaScript and C# code, including its architecture.</p>



<p>I think that TypeScript uses many simple concepts under the hood and it makes a lot of things possible (see <a href="https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-1.html#keyof-and-lookup-types" target="_blank" rel="noreferrer noopener">keyof</a> or <a href="https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-1.html#keyof-and-lookup-types" target="_blank" rel="noreferrer noopener">unknown</a>). In many cases TypeScript <em>lets</em> you do something, but <em>doesn&#8217;t force</em> you to do it. That&#8217;s the beauty of this typed JavaScript world <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f609.png" alt="😉" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>
<p>The post <a href="https://www.codejourney.net/is-it-worth-migrating-to-typescript/">Is It Worth Migrating to TypeScript?</a> appeared first on <a href="https://www.codejourney.net">CodeJourney.net</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.codejourney.net/is-it-worth-migrating-to-typescript/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">3840</post-id>	</item>
	</channel>
</rss>
