{"id":2147,"date":"2019-06-14T08:37:42","date_gmt":"2019-06-14T16:37:42","guid":{"rendered":"https:\/\/devblogs.microsoft.com\/typescript\/?p=2147"},"modified":"2019-06-24T08:30:16","modified_gmt":"2019-06-24T16:30:16","slug":"how-to-upgrade-to-typescript-without-anybody-noticing-part-1","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/typescript\/how-to-upgrade-to-typescript-without-anybody-noticing-part-1\/","title":{"rendered":"How to Upgrade to TypeScript Without Anybody Noticing, Part 1"},"content":{"rendered":"<p>This guide will show you how to upgrade to TypeScript without anybody noticing. Well, people <em>might<\/em> notice \u2014 what I really mean is that you won\u2019t have to change your build at all. You\u2019ll have the ability <a href=\"https:\/\/github.com\/Microsoft\/TypeScript\/wiki\/TypeScript-Editor-Support\">to get errors and completions in supported editors<\/a> and to get errors on the command line from <code class=\"highlighter-rouge\">tsc<\/code>, the TypeScript compiler, but you won\u2019t have to integrate TypeScript into your build.<\/p>\n<p>Here\u2019s what you\u2019ll actually need to check in to source control:<\/p>\n<ol>\n<li>A TypeScript configuration file, <code class=\"highlighter-rouge\">tsconfig.json<\/code>.<\/li>\n<li>New dev dependencies from the <code class=\"highlighter-rouge\">@types<\/code> package.<\/li>\n<li>A TypeScript declaration file to hold miscellaneous types.<\/li>\n<\/ol>\n<p>How can you upgrade with so little change? Well, the secret is that <em>you\u2019re not using TypeScript<\/em>. The TypeScript compiler can check Javascript just fine, so you can stick with Javascript and use JSDoc to provide type information. This is less convenient than TypeScript\u2019s syntax for types, but it means that your files stay plain old Javascript and your build (if any) doesn\u2019t change at all.<\/p>\n<p>Let\u2019s use <a href=\"https:\/\/github.com\/eslint\/TypeScript-eslint-parser\">TypeScript-eslint-parser<\/a> as an example package so you can follow along if you want. Confusingly, even though the name includes \u201cTypeScript\u201d, the parser is actually written in Javascript, although it has since been merged into <a href=\"https:\/\/github.com\/TypeScript-eslint\/TypeScript-eslint\">a larger project that is written in TypeScript<\/a>.<\/p>\n<p>This guide assumes that you have used TypeScript enough to:<\/p>\n<ol>\n<li><a href=\"https:\/\/github.com\/Microsoft\/TypeScript\/wiki\/TypeScript-Editor-Support\">Have an editor set up to work with TypeScript<\/a>.<\/li>\n<li>Have used npm to install a package.<\/li>\n<li><a href=\"http:\/\/2ality.com\/2018\/04\/type-notation-TypeScript.html\">Know the basic syntax of type annotations<\/a> \u2014 <code class=\"highlighter-rouge\">number<\/code>, <code class=\"highlighter-rouge\">{ x: any }<\/code>, etc.<\/li>\n<\/ol>\n<p>If you want to look at the package after the upgrade, you can run the following commands, or <a href=\"https:\/\/github.com\/eslint\/TypeScript-eslint-parser\/compare\/master...sandersn:add-tsconfig\">take a look at the branch on github<\/a>:<\/p>\n<div class=\"language-sh highlighter-rouge\">\n<div class=\"highlight\">\n<pre class=\"lang:default decode:true\" style=\"background-color: #f0f0f0;padding: 10px;border-radius: 10px;\"><code>git clone https:\/\/github.com\/sandersn\/TypeScript-eslint-parser\r\n<span class=\"nb\">cd <\/span>TypeScript-eslint-parser\r\ngit checkout add-tsconfig\r\nnpm install\r\n<\/code><\/pre>\n<\/div>\n<\/div>\n<p>Also make sure that you have TypeScript installed on the command line:<\/p>\n<div class=\"highlighter-rouge\">\n<div class=\"highlight\">\n<pre class=\"lang:default decode:true\" style=\"background-color: #f0f0f0;padding: 10px;border-radius: 10px;\">\r\n<code>npm install -g TypeScript\r\n<\/code><\/pre>\n<\/div>\n<\/div>\n<p>&nbsp;<\/p>\n<h2 id=\"add-tsconfig\">Add tsconfig<\/h2>\n<p>Your first step is to start with <code class=\"highlighter-rouge\">tsc --init<\/code> and change the settings in the <code class=\"highlighter-rouge\">tsconfig.json<\/code> that it produces. There are other ways to get started, but this gives you the most control. Run this command from the root of the project:<\/p>\n<div class=\"language-sh highlighter-rouge\">\n<div class=\"highlight\">\n<pre class=\"lang:default decode:true\" style=\"background-color: #f0f0f0;padding: 10px;border-radius: 10px;\"><code>tsc <span class=\"nt\">--init<\/span>\r\n<\/code><\/pre>\n<\/div>\n<\/div>\n<p>Here is what you should end up with, skipping the lines you don\u2019t need to change:<\/p>\n<div class=\"language-json highlighter-rouge\">\n<div class=\"highlight\">\n<pre class=\"lang:default decode:true\" style=\"background-color: #f0f0f0;padding: 10px;border-radius: 10px;\">\r\n<code><span class=\"p\">{<\/span>\r\n  <span style=\"color: #a31515;\">\"compilerOptions\"<\/span><span class=\"p\">:<\/span> <span class=\"p\">{<\/span>\r\n    <span style=\"color: #a31515;\">\"allowJs\"<\/span><span class=\"p\">:<\/span> <span class=\"kc\">true<\/span><span class=\"p\">,<\/span>\r\n    <span style=\"color: #a31515;\">\"checkJs\"<\/span><span class=\"p\">:<\/span> <span class=\"kc\">true<\/span><span class=\"p\">,<\/span>\r\n    <span style=\"color: #a31515;\">\"noEmit\"<\/span><span class=\"p\">:<\/span> <span class=\"kc\">true<\/span><span class=\"p\">,<\/span>\r\n    <span style=\"color: #a31515;\">\"target\"<\/span><span class=\"p\">:<\/span> <span style=\"color: #a31515;\">\"esnext\"<\/span><span class=\"p\">,<\/span>\r\n    <span style=\"color: #a31515;\">\"module\"<\/span><span class=\"p\">:<\/span> <span style=\"color: #a31515;\">\"commonjs\"<\/span><span class=\"p\">,<\/span>\r\n    <span style=\"color: #a31515;\">\"resolveJsonModule\"<\/span><span class=\"p\">:<\/span> <span class=\"kc\">true<\/span><span class=\"p\">,<\/span>\r\n    <span style=\"color: #a31515;\">\"strict\"<\/span><span class=\"p\">:<\/span> <span class=\"kc\">false<\/span>\r\n  <span class=\"p\">},<\/span>\r\n  <span style=\"color: #a31515;\">\"exclude\"<\/span><span class=\"p\">:<\/span> <span class=\"p\">[<\/span>\r\n    <span style=\"color: #a31515;\">\"tests\/fixtures\/\"<\/span><span class=\"p\">,<\/span>\r\n    <span style=\"color: #a31515;\">\"tests\/integration\/\"<\/span>\r\n  <span class=\"p\">]<\/span>\r\n<span class=\"p\">}<\/span>\r\n<\/code><\/pre>\n<\/div>\n<\/div>\n<p>For Javascript, your \u201ccompilerOptions\u201d will pretty much always look like this.<\/p>\n<ul>\n<li><code class=\"highlighter-rouge\">allowJs<\/code> \u2014 Compile JS files.<\/li>\n<li><code class=\"highlighter-rouge\">checkJs<\/code> \u2014 Give errors on JS files.<\/li>\n<li><code class=\"highlighter-rouge\">noEmit<\/code> \u2014 Don\u2019t emit downlevel code; just give errors.<\/li>\n<li><code class=\"highlighter-rouge\">target<\/code> \u2014 Target the newest version of EcmaScript since we\u2019re not emitting code anyway.<\/li>\n<li><code class=\"highlighter-rouge\">module<\/code> \u2014 Target node\u2019s module system since we\u2019re not emitting code anyway.<\/li>\n<li><code class=\"highlighter-rouge\">resolveJsonModule<\/code> \u2014 Compile JSON files (if they\u2019re small enough).<\/li>\n<li><code class=\"highlighter-rouge\">strict<\/code> \u2014 Don\u2019t give the strictest possible errors.<\/li>\n<\/ul>\n<p>A few notes:<\/p>\n<ul>\n<li><code class=\"highlighter-rouge\">\"target\"<\/code> and <code class=\"highlighter-rouge\">\"module\"<\/code> should not actually matter since they have to do with generated downlevel code, but you\u2019ll get some bogus errors if you use ES6 classes like <code class=\"highlighter-rouge\">Map<\/code> or <code class=\"highlighter-rouge\">Set<\/code>.<\/li>\n<li><code class=\"highlighter-rouge\">\"resolveJsonModule\"<\/code> is optional, but you\u2019ll need it if your code ever <code class=\"highlighter-rouge\">require<\/code>s a JSON file, so that TypeScript will analyze it too.<\/li>\n<li><code class=\"highlighter-rouge\">\"strict\"<\/code> should be false by default. You can satisfy the compiler on strict mode with pure Javascript, but it can require some odd code.<\/li>\n<\/ul>\n<p>You may want to specify which files to compile. For TypeScript-eslint-parser, you\u2019ll be happiest with an <code class=\"highlighter-rouge\">\"exclude\"<\/code> list. You <em>may<\/em> want to check <em>all<\/em> the source files, which is what you get by default. But it turns out that checking a Javascript parser\u2019s tests is a bad idea, because the tests are themselves malformed Javascript files. Those malformed test files shouldn\u2019t be checked and mostly don\u2019t parse anyway.<\/p>\n<p>You might want to use <code class=\"highlighter-rouge\">\"include\"<\/code> if, say, you only want to check your source and not your tests or scripts. Or you can use <code class=\"highlighter-rouge\">\"files\"<\/code> to give an explicit list of files to use, but this is annoying except for small projects.<\/p>\n<p>OK, you\u2019re all set. Run <code class=\"highlighter-rouge\">tsc<\/code> and make sure it prints out errors. Now open up files in your editor and make sure the same errors show up there. Below are the first few errors you should see:<\/p>\n<div class=\"highlighter-rouge\">\n<div class=\"highlight\">\n<pre class=\"lang:default decode:true\" style=\"background-color: #f0f0f0;padding: 10px;border-radius: 10px;\">\r\n<code>Makefile.js(55,18): error TS2304: Cannot find name 'find'.\r\nMakefile.js(56,19): error TS2304: Cannot find name 'find'.\r\nMakefile.js(70,5): error TS2304: Cannot find name 'echo'.\r\n<\/code><\/pre>\n<\/div>\n<\/div>\n<p>You should be able to see the same errors when you open Makefile.js in your editor and look at lines 55 and 56.<\/p>\n<p>Congratulations! You\u2019ve done the only <em>required<\/em> part of the upgrade. You can check in <code class=\"highlighter-rouge\">tsconfig.json<\/code> and start getting benefits from TypeScript\u2019s checking in the editor without changing anything else. Of course, there are a huge number of errors, hardly any of which are due to real bugs. So the next step is to start getting rid of incorrect errors and improving TypeScript\u2019s knowledge of the code.<\/p>\n<p><a href=\"https:\/\/github.com\/eslint\/TypeScript-eslint-parser\/commit\/9ee85f151b0ef81fa592ddbdb4f60aeb842ae42c\">Here\u2019s the commit.<\/a><\/p>\n<p>&nbsp;<\/p>\n<h2 id=\"install-types-packages\">Install @types packages.<\/h2>\n<p>Your first order of business is to install types for packages you use. This allows TypeScript to understand them, which makes it the easiest way to reduce the number of errors. Basically, if you have a dependency on some package, say, <code class=\"highlighter-rouge\">jquery<\/code>, and you see errors when you use it, you probably need a dev dependency on <code class=\"highlighter-rouge\">@types\/jquery<\/code>. The type definitions in <code class=\"highlighter-rouge\">@types\/jquery<\/code> give TypeScript a model of jquery that it can use to provide editor support, even though jquery was written before TypeScript existed.<\/p>\n<p><a href=\"https:\/\/github.com\/DefinitelyTyped\/DefinitelyTyped\">Definitely Typed<\/a> is the source for the packages in the <code class=\"highlighter-rouge\">@types<\/code> namespace. Anybody can contribute new type definitions, but tons of packages already have type definitions, so you will probably find that most of your dependencies do too.<\/p>\n<p><a href=\"https:\/\/github.com\/eslint\/TypeScript-eslint-parser\/commit\/0a8bf69fc1d8c0967e7e67ade2fec38ddfeefeda\">Here\u2019s a good starting set for TypeScript-eslint-parser<\/a>, although there are likely more available:<\/p>\n<div class=\"language-sh highlighter-rouge\">\n<div class=\"highlight\">\n<pre class=\"lang:default decode:true\" style=\"background-color: #f0f0f0;padding: 10px;border-radius: 10px;\"><code>npm install <span class=\"nt\">--save-dev<\/span> @types\/node\r\nnpm install <span class=\"nt\">--save-dev<\/span> @types\/jest\r\nnpm install <span class=\"nt\">--save-dev<\/span> @types\/estree\r\nnpm install <span class=\"nt\">--save-dev<\/span> @types\/shelljs@0.8.0\r\nnpm install <span class=\"nt\">--save-dev<\/span> @types\/eslint-scope\r\n<\/code><\/pre>\n<\/div>\n<\/div>\n<p>After the installation, these three types packages still didn\u2019t work (although notice that we intentionally installed an old version of shelljs \u2013 more on that later):<\/p>\n<ul>\n<li><code class=\"highlighter-rouge\">@types\/shelljs<\/code><\/li>\n<li><code class=\"highlighter-rouge\">@types\/eslint-scope<\/code><\/li>\n<li><code class=\"highlighter-rouge\">@types\/estree<\/code><\/li>\n<\/ul>\n<p>They fail for different reasons, though. shelljs and es-lint-scope just don\u2019t have types for a lot of their values. estree <em>has<\/em> all the correct types, but the types aren\u2019t imported correctly.<a href=\"https:\/\/sandersn.github.io\/manual\/How-to-upgrade-to-TypeScript-without-anybody-noticing-part-2.html\">Part 2<\/a> shows how to fix these two problems.<\/p>\n<p>At this point, you have types for some of your packages working and your own code checked by the TypeScript compiler. The next step is to fix compile errors in the rest of the package types, or to fix them in your own code. Or you can just ignore the errors and start using the TypeScript support in the editor.<\/p>\n<p>Next up: <a href=\"https:\/\/devblogs.microsoft.com\/typescript\/how-to-upgrade-to-typescript-without-anybody-noticing-part-2\/\">Part 2<\/a>, to learn about the various kinds of fixes.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>This guide will show you how to upgrade to TypeScript without anybody noticing. Well, people might notice \u2014 what I really mean is that you won\u2019t have to change your build at all. You\u2019ll have the ability to get errors and completions in supported editors and to get errors on the command line from tsc, [&hellip;]<\/p>\n","protected":false},"author":1338,"featured_media":1797,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[],"class_list":["post-2147","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-typescript"],"acf":[],"blog_post_summary":"<p>This guide will show you how to upgrade to TypeScript without anybody noticing. Well, people might notice \u2014 what I really mean is that you won\u2019t have to change your build at all. You\u2019ll have the ability to get errors and completions in supported editors and to get errors on the command line from tsc, [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/typescript\/wp-json\/wp\/v2\/posts\/2147","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/typescript\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/typescript\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/typescript\/wp-json\/wp\/v2\/users\/1338"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/typescript\/wp-json\/wp\/v2\/comments?post=2147"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/typescript\/wp-json\/wp\/v2\/posts\/2147\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/typescript\/wp-json\/wp\/v2\/media\/1797"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/typescript\/wp-json\/wp\/v2\/media?parent=2147"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/typescript\/wp-json\/wp\/v2\/categories?post=2147"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/typescript\/wp-json\/wp\/v2\/tags?post=2147"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}