{"id":1285,"date":"2018-01-31T17:31:26","date_gmt":"2018-01-31T17:31:26","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/typescript\/?p=1285"},"modified":"2021-08-10T09:48:43","modified_gmt":"2021-08-10T17:48:43","slug":"announcing-typescript-2-7","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/typescript\/announcing-typescript-2-7\/","title":{"rendered":"Announcing TypeScript 2.7"},"content":{"rendered":"<div id=\"readme\" class=\"readme blob instapaper_body\">\n<article class=\"markdown-body entry-content\">Today we&#8217;re proud to announce the release of TypeScript 2.7!<\/p>\n<p>If you&#8217;re not familiar with TypeScript, it&#8217;s a language that brings optional static types to JavaScript by building on JavaScript itself. Running TypeScript code through its compiler emits clean readable JavaScript that runs on any browser, and can also make bleeding-edge ECMAScript features you write work on older browsers. That means that you can take advantage of the design time tooling and safety of types (like code completion &amp; navigation), while still leveraging the familiarity, community, and ubiquity of JavaScript.<\/p>\n<p>But if you already know what TypeScript is and want to start using 2.7, go ahead and get it <a href=\"https:\/\/www.nuget.org\/packages\/Microsoft.TypeScript.MSBuild\" rel=\"nofollow\">on NuGet<\/a> or download it over npm:<\/p>\n<div class=\"highlight highlight-source-shell\">\n<pre>npm install -g typescript<\/pre>\n<\/div>\n<p>Visual Studio 2015 users (who have <a href=\"https:\/\/www.visualstudio.com\/en-us\/news\/releasenotes\/vs2015-update3-vs\" rel=\"nofollow\">Update 3<\/a>) can install TypeScript 2.7 <a href=\"http:\/\/download.microsoft.com\/download\/6\/D\/8\/6D8381B0-03C1-4BD2-AE65-30FF0A4C62DA\/2.7.1-TS-release-dev14update3-20180130.1\/TypeScript_Dev14Full.exe\" rel=\"nofollow\">from here<\/a>, and Visual Studio 2017 users using version 15.2 or later will be able to get TypeScript by simply <a href=\"http:\/\/download.microsoft.com\/download\/7\/0\/A\/70A6AC0E-8934-4396-A43E-445059F430EA\/2.7.1-TS-release-dev14update3-20180130.1\/TypeScript_SDK.exe\" rel=\"nofollow\">installing it from here<\/a>. Sublime Text Plugin users can install the new version <a href=\"https:\/\/packagecontrol.io\/packages\/TypeScript\" rel=\"nofollow\">from Package Control<\/a>.<\/p>\n<p>TypeScript 2.7 will be available for Visual Studio Code very soon, but <a href=\"https:\/\/code.visualstudio.com\/Docs\/languages\/typescript#_using-newer-typescript-versions\" rel=\"nofollow\">eager users can get it working pretty easily in the meantime<\/a>.<\/p>\n<p>We&#8217;ve got a lot in 2.7. While you can always take a look at <a href=\"https:\/\/github.com\/Microsoft\/TypeScript\/wiki\/Roadmap\">the roadmap<\/a>, we&#8217;ve put together a quick list for a bird&#8217;s eye view of this release:<\/p>\n<ul>\n<li><a href=\"#stricter-class-property-checks\">Stricter class property checks<\/a><\/li>\n<li><a href=\"#definite-assignment-assertions\">Definite assignment assertions<\/a><\/li>\n<li><a href=\"#easier-ecmascript-module-interoperability\">Easier ECMAScript module interoperability<\/a><\/li>\n<li><a href=\"#unique-symbol-types-and-const-named-properties\"><code>unique symbol<\/code> types and const-named properties<\/a><\/li>\n<li><a href=\"#cleaner-output-in-watch-mode\">Cleaner output in <code>--watch<\/code> mode<\/a><\/li>\n<li><a href=\"#prettier-pretty-output\">Prettier <code>--pretty<\/code> output<\/a><\/li>\n<li><a href=\"#numeric-separators\">Numeric Separators<\/a><\/li>\n<li><a href=\"#fixed-length-tuples\">Fixed Length Tuples<\/a><\/li>\n<li><a href=\"#in-operator-narrowing-and-accurate-instanceof\"><code>in<\/code> operator narrowing and accurate <code>instanceof<\/code><\/a><\/li>\n<li><a href=\"#smarter-object-literal-inference\">Smarter object literal inference<\/a><\/li>\n<\/ul>\n<p>We&#8217;ve also put together a <a href=\"#breaking-changes\">breaking changes<\/a> section towards the end of this post which existing users should be aware of.<\/p>\n<p>So without further ado, let&#8217;s see what this release brings!<\/p>\n<h2 id=\"stricter-class-property-checks\">Stricter class property checks<\/h2>\n<p>TypeScript 2.7 introduces a new strictness flag named <code>--strictPropertyInitialization<\/code>!<\/p>\n<p>This flag makes sure that each instance property of a class gets set in the constructor body, or by a property initializer. In a sense, it brings some of the definite assignment checks from variables to instance properties in classes. For example:<\/p>\n<div class=\"highlight highlight-source-ts\">\n<pre><span style=\"color: #0000ff\">class<\/span> <span style=\"color: #267F99\">C<\/span> {\r\n    foo<span class=\"pl-k\">:<\/span> <span style=\"color: #0000ff\">number<\/span>;\r\n    bar <span class=\"pl-k\">=<\/span> <span style=\"color: #a31515\"><span class=\"pl-pds\">\"<\/span>hello<span class=\"pl-pds\">\"<\/span><\/span>;\r\n    baz<span class=\"pl-k\">:<\/span> <span style=\"color: #0000ff\">boolean<\/span>;\r\n<span style=\"color: #148A14\">\/\/  ~~~<\/span>\r\n<span style=\"color: #148A14\">\/\/  Error! Property 'baz' has no initializer and is not assigned directly in the constructor.<\/span>\r\n    <span style=\"color: #0000ff\">constructor<\/span>() {\r\n        <span style=\"color: #0000ff\">this<\/span>.<span class=\"pl-smi\">foo<\/span> <span class=\"pl-k\">=<\/span> <span style=\"color: #09885A\">42<\/span>;\r\n    }\r\n}<\/pre>\n<\/div>\n<p>In the above, <code>baz<\/code> never gets set, and TypeScript reports an error. If we truly meant for <code>baz<\/code> to potentially be <code>undefined<\/code>, we should have declared it with the type <code>boolean | undefined<\/code>.<\/p>\n<p>There are certain scenarios where properties might be initialized indirectly (perhaps by a helper method or dependency injection library). In those cases, you can convince the type system you know better by using the <em>definite assignment assertions<\/em> for your properties.<\/p>\n<div class=\"highlight highlight-source-ts\">\n<pre><span style=\"color: #0000ff\">class<\/span> <span style=\"color: #267F99\">C<\/span> {\r\n    <span class=\"pl-smi\">foo<\/span><span class=\"pl-k\">!<\/span><span class=\"pl-k\">:<\/span> <span style=\"color: #0000ff\">number<\/span>;\r\n    <span style=\"color: #148A14\">\/\/ ^<\/span>\r\n    <span style=\"color: #148A14\">\/\/ Notice this exclamation point!<\/span>\r\n    <span style=\"color: #148A14\">\/\/ This is the \"definite assignment assertion\" modifier.<\/span>\r\n    <span style=\"color: #0000ff\">constructor<\/span>() {\r\n        <span style=\"color: #0000ff\">this<\/span>.<span class=\"pl-en\">initialize<\/span>();\r\n    }\r\n\r\n    initialize() {\r\n        <span style=\"color: #0000ff\">this<\/span>.<span class=\"pl-smi\">foo<\/span> <span class=\"pl-k\">=<\/span> <span style=\"color: #09885A\">0<\/span>;\r\n    }\r\n}<\/pre>\n<\/div>\n<p>Keep in mind that <code>--strictPropertyInitialization<\/code> will be turned on along with other <code>--strict<\/code> mode flags, which can impact your project. You can set the <code>strictPropertyInitialization<\/code> setting to <code>false<\/code> in your <code>tsconfig.json<\/code>&#8216;s <code>compilerOptions<\/code>, or <code>--strictPropertyInitialization false<\/code> on the command line to turn off this checking.<\/p>\n<h2 id=\"definite-assignment-assertions\">Definite assignment assertions<\/h2>\n<p>As expressive as we try to make the type system, we understand there are certain times you might know better than TypeScript.<\/p>\n<p>As we mentioned above, definite assignment assertions are a new syntax you can use to convince TypeScript that a property will definitely get assigned. But in addition to working on class properties, TypeScript 2.7 also allows you to use this feature on variable declarations!<\/p>\n<div class=\"highlight highlight-source-ts\">\n<pre><span style=\"color: #0000ff\">let<\/span> x!<span class=\"pl-k\">:<\/span> <span style=\"color: #0000ff\">number<\/span>[];\r\n<span class=\"pl-en\">initialize<\/span>();\r\n<span class=\"pl-smi\">x<\/span>.<span class=\"pl-c1\">push<\/span>(<span style=\"color: #09885A\">4<\/span>);\r\n\r\n<span style=\"color: #0000ff\">function<\/span> initialize() {\r\n    <span class=\"pl-smi\">x<\/span> <span class=\"pl-k\">=<\/span> [<span style=\"color: #09885A\">0<\/span>, <span style=\"color: #09885A\">1<\/span>, <span style=\"color: #09885A\">2<\/span>, <span style=\"color: #09885A\">3<\/span>];\r\n}<\/pre>\n<\/div>\n<p>If we hadn&#8217;t added an exclamation point\/bang (<code>!<\/code>) after <code>x<\/code>, TypeScript would have reported that <code>x<\/code> was never initialized. This can be handy in deferred-initialization, or re-initialization scenarios.<\/p>\n<h2 id=\"easier-ecmascript-module-interoperability\">Easier ECMAScript module interoperability<\/h2>\n<p>Before ECMAScript modules were standardized in ES2015, the JavaScript ecosystem had several different module formats that worked in different ways. Once the standard passed, the community was left with a question of how to best interoperate with existing &#8220;legacy&#8221; module formats.<\/p>\n<p>TypeScript and Babel took different approaches, and even now, there really isn&#8217;t a locked down standard. The short story is that if you&#8217;ve used Babel, Webpack, or React Native, and expected different import behaviors than you were used to, we have a new compiler option for you called <code>--esModuleInterop<\/code>.<\/p>\n<p>Babel and Webpack allow users to import these CommonJS modules as default imports, but also provide each property on the namespace import (unless the module was marked with an <code>__esModule<\/code> flag).<\/p>\n<div class=\"highlight highlight-source-ts\">\n<pre><span style=\"color: #0000ff\">import<\/span> <span class=\"pl-smi\">_<\/span>, { <span class=\"pl-smi\">pick<\/span> } <span style=\"color: #0000ff\">from<\/span> <span style=\"color: #a31515\"><span class=\"pl-pds\">\"<\/span>lodash<span class=\"pl-pds\">\"<\/span><\/span>;\r\n\r\n<span class=\"pl-smi\">_<\/span>.<span class=\"pl-en\">pick<\/span>(<span class=\"pl-k\">...<\/span>);\r\n<span class=\"pl-en\">pick<\/span>(<span class=\"pl-k\">...<\/span>);<\/pre>\n<\/div>\n<p>Because TypeScript&#8217;s behavior differs, we added the <code>--allowSyntheticDefaultImports<\/code> flag in TypeScript 1.8 to allow users to get this behavior for type-checking (but not emit).<\/p>\n<p>In general, TypeScript&#8217;s view of CommonJS (and AMD) modules is that namespace imports always correspond to the shape of a CommonJS module object, and that a <code>default<\/code> import just corresponds to a member on that module named <code>default<\/code>. Under this assumption, you can create a named import<\/p>\n<div class=\"highlight highlight-source-ts\">\n<pre><span style=\"color: #0000ff\">import<\/span> { <span class=\"pl-smi\">range<\/span> } <span style=\"color: #0000ff\">from<\/span> <span style=\"color: #a31515\"><span class=\"pl-pds\">\"<\/span>lodash<span class=\"pl-pds\">\"<\/span><\/span>;\r\n\r\n<span style=\"color: #0000ff\">for<\/span> (<span style=\"color: #0000ff\">let<\/span> i <span style=\"color: #0000ff\">of<\/span> <span class=\"pl-en\">range<\/span>(<span style=\"color: #09885A\">10<\/span>)) {\r\n    <span style=\"color: #148A14\">\/\/ ...<\/span>\r\n}<\/pre>\n<\/div>\n<p>However, ES namespace imports aren&#8217;t callable, so this approach doesn&#8217;t always make sense.<\/p>\n<div class=\"highlight highlight-source-ts\">\n<pre><span style=\"color: #0000ff\">import<\/span> <span class=\"pl-c1\">*<\/span> <span style=\"color: #0000ff\">as<\/span> <span class=\"pl-smi\">express<\/span> <span style=\"color: #0000ff\">from<\/span> <span style=\"color: #a31515\"><span class=\"pl-pds\">\"<\/span>express<span class=\"pl-pds\">\"<\/span><\/span>;\r\n\r\n<span style=\"color: #148A14\">\/\/ Should be an error in any valid implementation.<\/span>\r\n<span style=\"color: #0000ff\">let<\/span> app <span class=\"pl-k\">=<\/span> <span class=\"pl-en\">express<\/span>();<\/pre>\n<\/div>\n<p>To give users the same runtime behavior as Babel or Webpack, TypeScript provides a new <code>--esModuleInterop<\/code> flag when emitting to<\/p>\n<p>legacy module formats.<\/p>\n<p>Under the new <code>--esModuleInterop<\/code> flag, these callable CommonJS modules <em>must<\/em> be imported as default imports like so:<\/p>\n<div class=\"highlight highlight-source-ts\">\n<pre><span style=\"color: #0000ff\">import<\/span> <span class=\"pl-smi\">express<\/span> <span style=\"color: #0000ff\">from<\/span> <span style=\"color: #a31515\"><span class=\"pl-pds\">\"<\/span>express<span class=\"pl-pds\">\"<\/span><\/span>;\r\n\r\n<span style=\"color: #0000ff\">let<\/span> app <span class=\"pl-k\">=<\/span> <span class=\"pl-en\">express<\/span>();<\/pre>\n<\/div>\n<p>We strongly suggest that Node.js users leverage this flag with a module target of <code>commonjs<\/code> for libraries like express, which export a callable\/constructable module.<\/p>\n<p>Webpack users may want to use this as well; however, your code should target <code>esnext<\/code> modules with a <code>moduleResolution<\/code> strategy of <code>node<\/code>. Using <code>esnext<\/code> modules with <code>--esModuleInterop<\/code> really only has the effect of turning on <code>--allowSyntheticDefaultImports<\/code>.<\/p>\n<h2 id=\"unique-symbol-types-and-const-named-properties\"><code style=\"color: #a31515;font-size: 29px\">unique symbol<\/code> types and const-named properties<\/h2>\n<p>TypeScript 2.7 understands ECMAScript symbols more deeply, allowing you to use them more flexibly.<\/p>\n<p>One highly-demanded use-case is being able to declare well-typed properties with symbols. For an example, take the following:<\/p>\n<div class=\"highlight highlight-source-ts\">\n<pre><span style=\"color: #0000ff\">const<\/span> Foo <span class=\"pl-k\">=<\/span> <span style=\"color: #267F99\">Symbol<\/span>(<span style=\"color: #a31515\"><span class=\"pl-pds\">\"<\/span>Foo<span class=\"pl-pds\">\"<\/span><\/span>);\r\n<span style=\"color: #0000ff\">const<\/span> Bar <span class=\"pl-k\">=<\/span> <span style=\"color: #267F99\">Symbol<\/span>(<span style=\"color: #a31515\"><span class=\"pl-pds\">\"<\/span>Bar<span class=\"pl-pds\">\"<\/span><\/span>);\r\n\r\n<span style=\"color: #0000ff\">let<\/span> x <span class=\"pl-k\">=<\/span> {\r\n    [<span class=\"pl-smi\">Foo<\/span>]: <span style=\"color: #09885A\">100<\/span>,\r\n    [<span class=\"pl-smi\">Bar<\/span>]: <span style=\"color: #a31515\"><span class=\"pl-pds\">\"<\/span>hello<span class=\"pl-pds\">\"<\/span><\/span>,\r\n};\r\n\r\n<span style=\"color: #0000ff\">let<\/span> a <span class=\"pl-k\">=<\/span> <span class=\"pl-smi\">x<\/span>[<span class=\"pl-smi\">Foo<\/span>]; <span style=\"color: #148A14\">\/\/ has type 'number'<\/span>\r\n<span style=\"color: #0000ff\">let<\/span> b <span class=\"pl-k\">=<\/span> <span class=\"pl-smi\">x<\/span>[<span class=\"pl-smi\">Bar<\/span>]; <span style=\"color: #148A14\">\/\/ has type 'string'<\/span><\/pre>\n<\/div>\n<p>As you can see, TypeScript can keep track of the fact that <code>x<\/code> has properties declared using the symbols <code>Foo<\/code> and <code>Bar<\/code> since both <code>Foo<\/code> and <code>Bar<\/code> were declared as constants. TypeScript leverages this fact and gives both <code>Foo<\/code> and <code>Bar<\/code> a new kind of type: <code>unique symbol<\/code>s.<\/p>\n<p><code>unique symbol<\/code>s are subtype of <code>symbol<\/code>, and are produced only from calling <code>Symbol()<\/code> or <code>Symbol.for()<\/code>, or from explicit type annotations. They can only occur on <code>const<\/code> declarations and <code>readonly static<\/code> properties, and in order to reference an existing unique symbol type, you&#8217;ll have to use the <code>typeof<\/code> operator. Each reference to a <code>unique symbol<\/code> implies a completely unique identity that&#8217;s tied to a given declaration.<\/p>\n<div class=\"highlight highlight-source-ts\">\n<pre><span style=\"color: #148A14\">\/\/ Works<\/span>\r\n<span style=\"color: #0000ff\">declare<\/span> <span style=\"color: #0000ff\">const<\/span> Foo<span class=\"pl-k\">:<\/span> <span style=\"color: #0000ff\">unique<\/span> <span style=\"color: #0000ff\">symbol<\/span>;\r\n\r\n<span style=\"color: #148A14\">\/\/ Error! 'Bar' isn't a constant.<\/span>\r\n<span style=\"color: #0000ff\">let<\/span> Bar<span class=\"pl-k\">:<\/span> <span style=\"color: #0000ff\">unique<\/span> <span style=\"color: #0000ff\">symbol<\/span> <span class=\"pl-k\">=<\/span> <span style=\"color: #267F99\">Symbol<\/span>();\r\n\r\n<span style=\"color: #148A14\">\/\/ Works - refers to a unique symbol, but its identity is tied to 'Foo'.<\/span>\r\n<span style=\"color: #0000ff\">let<\/span> Baz<span class=\"pl-k\">:<\/span> <span style=\"color: #0000ff\">typeof<\/span> <span style=\"color: #267F99\">Foo<\/span> <span class=\"pl-k\">=<\/span> <span class=\"pl-smi\">Foo<\/span>;\r\n\r\n<span style=\"color: #148A14\">\/\/ Also works.<\/span>\r\n<span style=\"color: #0000ff\">class<\/span> <span style=\"color: #267F99\">C<\/span> {\r\n    <span style=\"color: #0000ff\">static<\/span> <span style=\"color: #0000ff\">readonly<\/span> StaticSymbol<span class=\"pl-k\">:<\/span> <span style=\"color: #0000ff\">unique<\/span> <span style=\"color: #0000ff\">symbol<\/span> <span class=\"pl-k\">=<\/span> <span style=\"color: #267F99\">Symbol<\/span>();\r\n}<\/pre>\n<\/div>\n<p>Because each <code>unique symbol<\/code> has a completely separate identity, no two <code>unique symbol<\/code> types are assignable or comparable to each other.<\/p>\n<div class=\"highlight highlight-source-ts\">\n<pre><span style=\"color: #0000ff\">const<\/span> Foo <span class=\"pl-k\">=<\/span> <span style=\"color: #267F99\">Symbol<\/span>();\r\n<span style=\"color: #0000ff\">const<\/span> Bar <span class=\"pl-k\">=<\/span> <span style=\"color: #267F99\">Symbol<\/span>();\r\n\r\n<span style=\"color: #148A14\">\/\/ Error: can't compare two unique symbols.<\/span>\r\n<span style=\"color: #0000ff\">if<\/span> (<span class=\"pl-smi\">Foo<\/span> <span class=\"pl-k\">===<\/span> <span class=\"pl-smi\">Bar<\/span>) {\r\n    <span style=\"color: #148A14\">\/\/ ...<\/span>\r\n}<\/pre>\n<\/div>\n<p>Other potential use-cases include using symbols for tagged unions.<\/p>\n<div class=\"highlight highlight-source-ts\">\n<pre><span style=\"color: #148A14\">\/\/ .\/ShapeKind.ts<\/span>\r\n<span style=\"color: #0000ff\">export<\/span> <span style=\"color: #0000ff\">const<\/span> Circle <span class=\"pl-k\">=<\/span> <span style=\"color: #267F99\">Symbol<\/span>(<span style=\"color: #a31515\"><span class=\"pl-pds\">\"<\/span>circle<span class=\"pl-pds\">\"<\/span><\/span>);\r\n<span style=\"color: #0000ff\">export<\/span> <span style=\"color: #0000ff\">const<\/span> Square <span class=\"pl-k\">=<\/span> <span style=\"color: #267F99\">Symbol<\/span>(<span style=\"color: #a31515\"><span class=\"pl-pds\">\"<\/span>square<span class=\"pl-pds\">\"<\/span><\/span>);\r\n\r\n<span style=\"color: #148A14\">\/\/ .\/ShapeFun.ts<\/span>\r\n<span style=\"color: #0000ff\">import<\/span> <span class=\"pl-c1\">*<\/span> <span style=\"color: #0000ff\">as<\/span> <span class=\"pl-smi\">ShapeKind<\/span> <span style=\"color: #0000ff\">from<\/span> <span style=\"color: #a31515\"><span class=\"pl-pds\">\"<\/span>.\/ShapeKind<span class=\"pl-pds\">\"<\/span><\/span>;\r\n\r\n<span style=\"color: #0000ff\">interface<\/span> <span style=\"color: #267F99\">Circle<\/span> {\r\n    kind<span class=\"pl-k\">:<\/span> <span style=\"color: #0000ff\">typeof<\/span> <span style=\"color: #267F99\">ShapeKind<\/span>.<span style=\"color: #267F99\">Circle<\/span>;\r\n    radius<span class=\"pl-k\">:<\/span> <span style=\"color: #0000ff\">number<\/span>;\r\n}\r\n\r\n<span style=\"color: #0000ff\">interface<\/span> <span style=\"color: #267F99\">Square<\/span> {\r\n    kind<span class=\"pl-k\">:<\/span> <span style=\"color: #0000ff\">typeof<\/span> <span style=\"color: #267F99\">ShapeKind<\/span>.<span style=\"color: #267F99\">Square<\/span>;\r\n    sideLength<span class=\"pl-k\">:<\/span> <span style=\"color: #0000ff\">number<\/span>;\r\n}\r\n\r\n<span style=\"color: #0000ff\">function<\/span> area(<span class=\"pl-v\">shape<\/span><span class=\"pl-k\">:<\/span> <span style=\"color: #267F99\">Circle<\/span> <span class=\"pl-k\">|<\/span> <span style=\"color: #267F99\">Square<\/span>) {\r\n    <span style=\"color: #0000ff\">if<\/span> (<span class=\"pl-smi\">shape<\/span>.<span class=\"pl-smi\">kind<\/span> <span class=\"pl-k\">===<\/span> <span class=\"pl-smi\">ShapeKind<\/span>.<span class=\"pl-smi\">Circle<\/span>) {\r\n        <span style=\"color: #148A14\">\/\/ 'shape' has type 'Circle'<\/span>\r\n        <span style=\"color: #0000ff\">return<\/span> <span class=\"pl-c1\">Math<\/span>.<span class=\"pl-c1\">PI<\/span> <span class=\"pl-k\">*<\/span> <span class=\"pl-smi\">shape<\/span>.<span class=\"pl-smi\">radius<\/span> <span class=\"pl-k\">**<\/span> <span style=\"color: #09885A\">2<\/span>;\r\n    }\r\n    <span style=\"color: #148A14\">\/\/ 'shape' has type 'Square'<\/span>\r\n    <span style=\"color: #0000ff\">return<\/span> <span class=\"pl-smi\">shape<\/span>.<span class=\"pl-smi\">sideLength<\/span> <span class=\"pl-k\">**<\/span> <span style=\"color: #09885A\">2<\/span>;\r\n}<\/pre>\n<\/div>\n<h2 id=\"cleaner-output-in-watch-mode\">Cleaner output in <code style=\"color: #a31515;font-size: 29px\">--watch<\/code> mode<\/h2>\n<p>TypeScript&#8217;s <code>--watch<\/code> mode now clears the screen after a re-compilation is requested. This can make it much easier to read messages from the current compilation. We&#8217;d like to thank both <a href=\"https:\/\/github.com\/k0pernikus\">Philipp Kretzschmar<\/a> and <a href=\"https:\/\/github.com\/JoshuaKGoldberg\">Joshua Goldberg<\/a> for helping out on this feature!<\/p>\n<h2 id=\"prettier-pretty-output\">Prettier <code style=\"color: #a31515;font-size: 29px\">--pretty<\/code> output<\/h2>\n<p>TypeScript&#8217;s <code>--pretty<\/code> flag can make error messages easier to read and manage. We have two main improvements in this functionality. First, thanks to <a href=\"https:\/\/github.com\/Microsoft\/TypeScript\/pull\/20416\">a pull request<\/a> from <a href=\"https:\/\/github.com\/JoshuaKGoldberg\">Joshua Goldberg<\/a> <code>--pretty<\/code> now uses colors for file names, diagnostic codes, and line numbers. Second, thanks to <a href=\"https:\/\/github.com\/Microsoft\/TypeScript\/pull\/20736\">a separate pull request<\/a> by <a href=\"https:\/\/github.com\/orta\">Orta Therox<\/a>, file names and positions are formatted in such a way that common terminals (including the one embedded in Visual Studio Code) can allow a Ctrl+Click, Cmd+Click, Alt+Click, etc. to jump to the appropriate location in your editor<\/p>\n<h2 id=\"numeric-separators\">Numeric Separators<\/h2>\n<p>TypeScript 2.7 introduces support for ECMAScript&#8217;s <a href=\"https:\/\/github.com\/tc39\/proposal-numeric-separator\">numeric separators<\/a> proposal. This feature allows users to place underscores (<code>_<\/code>) in between digits to visually distinguish groups of digits (<a href=\"https:\/\/en.wikipedia.org\/wiki\/Decimal_separator#Digit_grouping\">much like how commas and periods are often used to group numbers<\/a>).<\/p>\n<div class=\"highlight highlight-source-ts\">\n<pre><span style=\"color: #148A14\">\/\/ Constants<\/span>\r\n<span style=\"color: #0000ff\">const<\/span> COULOMB <span class=\"pl-k\">=<\/span> <span style=\"color: #09885A\">8.957_551_787e9<\/span>; <span style=\"color: #148A14\">\/\/ N-m^2 \/ C^2<\/span>\r\n<span style=\"color: #0000ff\">const<\/span> PLANCK <span class=\"pl-k\">=<\/span> <span style=\"color: #09885A\">6.626_070_040e-34<\/span>; <span style=\"color: #148A14\">\/\/ J-s<\/span>\r\n<span style=\"color: #0000ff\">const<\/span> JENNY <span class=\"pl-k\">=<\/span> <span style=\"color: #09885A\">867_5309<\/span>; <span style=\"color: #148A14\">\/\/ C-A-L^2<\/span><\/pre>\n<\/div>\n<p>These separators are also useful for binary and hexadecimal numbers.<\/p>\n<div class=\"highlight highlight-source-ts\">\n<pre><span style=\"color: #0000ff\">let<\/span> bits <span class=\"pl-k\">=<\/span> <span style=\"color: #09885A\">0b0010_1010<\/span>;\r\n<span style=\"color: #0000ff\">let<\/span> routine <span class=\"pl-k\">=<\/span> <span style=\"color: #09885A\">0xC0FFEE_F00D_BED<\/span>;\r\n<span style=\"color: #0000ff\">let<\/span> martin <span class=\"pl-k\">=<\/span> <span style=\"color: #09885A\">0xF0_1E_<\/span><\/pre>\n<\/div>\n<p>Note that, perhaps counterintuitively, numbers in JavaScript are not well-suited to represent credit card and telephone numbers. Strings will act as better representations in such cases.<\/p>\n<h2 id=\"fixed-length-tuples\">Fixed Length Tuples<\/h2>\n<p>In TypeScript 2.6 and earlier, <code>[number, string, string]<\/code> was considered a subtype of <code>[number, string]<\/code>. This was motivated by TypeScript&#8217;s structural nature; the first and second elements of a <code>[number, string, string]<\/code> are respectively subtypes of the first and second elements of <code>[number, string]<\/code>, and the &#8220;trailing&#8221; <code>string<\/code> type is assignable to the union of element types from <code>[number, string]<\/code>. However, after examining real world usage of tuples, we noticed that most situations in which this was permitted was typically undesirable.<\/p>\n<p>Thanks to a pull request from <a href=\"https:\/\/github.com\/KiaraGrouwstra\">Kiara Grouwstra<\/a>, tuple types now encode their arity into the type of their respective <code>length<\/code> property, and tuples of different arities are no longer assignable to each other. This is accomplished by leveraging numeric literal types, which now allow tuples to be distinct from tuples of different arities.<\/p>\n<p>Conceptually, you might consider the type <code>[number, string]<\/code> to be equivalent to the following declaration of <code>NumStrTuple<\/code>:<\/p>\n<div class=\"highlight highlight-source-ts\">\n<pre><span style=\"color: #0000ff\">interface<\/span> <span style=\"color: #267F99\">NumStrTuple<\/span> <span style=\"color: #0000ff\">extends<\/span> <span style=\"color: #267F99\">Array<\/span>&lt;<span style=\"color: #0000ff\">number<\/span> <span class=\"pl-k\">|<\/span> <span style=\"color: #0000ff\">string<\/span>&gt; {\r\n    <span style=\"color: #09885A\">0<\/span><span class=\"pl-k\">:<\/span> <span style=\"color: #0000ff\">number<\/span>;\r\n    <span style=\"color: #09885A\">1<\/span><span class=\"pl-k\">:<\/span> <span style=\"color: #0000ff\">string<\/span>;\r\n    length<span class=\"pl-k\">:<\/span> <span style=\"color: #09885A\">2<\/span>; <span style=\"color: #148A14\">\/\/ using the numeric literal type '2'<\/span>\r\n}<\/pre>\n<\/div>\n<p>Note that this is a breaking change. If you need to resort to the original behavior in which tuples only enforce a minimum size, you can use a similar declaration that does not explicitly define a <code>length<\/code> property, falling back to <code>number<\/code>.<\/p>\n<div class=\"highlight highlight-source-ts\">\n<pre><span style=\"color: #0000ff\">interface<\/span> <span style=\"color: #267F99\">MinimumNumStrTuple<\/span> <span style=\"color: #0000ff\">extends<\/span> <span style=\"color: #267F99\">Array<\/span>&lt;<span style=\"color: #0000ff\">number<\/span> <span class=\"pl-k\">|<\/span> <span style=\"color: #0000ff\">string<\/span>&gt; {\r\n    <span style=\"color: #09885A\">0<\/span><span class=\"pl-k\">:<\/span> <span style=\"color: #0000ff\">number<\/span>;\r\n    <span style=\"color: #09885A\">1<\/span><span class=\"pl-k\">:<\/span> <span style=\"color: #0000ff\">string<\/span>;\r\n}<\/pre>\n<\/div>\n<h2 id=\"in-operator-narrowing-and-accurate-instanceof\"><code style=\"color: #a31515;font-size: 29px\">in<\/code> operator narrowing and accurate <code style=\"color: #a31515;font-size: 29px\">instanceof<\/code><\/h2>\n<p>TypeScript 2.7 brings two new changes to type narrowing &#8211; the ability to get a more specific type for a value by running certain types of checks called &#8220;type guards&#8221;.<\/p>\n<p>First, the <code>instanceof<\/code> operator is now leverages the inheritance chain instead of<\/p>\n<p>relying on structural compatibility, more accurately reflecting whether how <code>instanceof<\/code> may behave at runtime. This can help avoid certain complex issues when <code>instanceof<\/code> narrows from structurally similar (but unrelated) types.<\/p>\n<p>Second, thanks to GitHub user <a href=\"https:\/\/github.com\/ideahunter\">IdeaHunter<\/a>, the <code>in<\/code> operator <a href=\"https:\/\/github.com\/Microsoft\/TypeScript\/pull\/15256\">now acts as a type guard<\/a>, narrowing out types that don&#8217;t explicitly declare properties of a given name.<\/p>\n<div class=\"highlight highlight-source-ts\">\n<pre><span style=\"color: #0000ff\">interface<\/span> <span style=\"color: #267F99\">A<\/span> { a<span class=\"pl-k\">:<\/span> <span style=\"color: #0000ff\">number<\/span> };\r\n<span style=\"color: #0000ff\">interface<\/span> <span style=\"color: #267F99\">B<\/span> { b<span class=\"pl-k\">:<\/span> <span style=\"color: #0000ff\">string<\/span> };\r\n\r\n<span style=\"color: #0000ff\">function<\/span> foo(<span class=\"pl-v\">x<\/span><span class=\"pl-k\">:<\/span> <span style=\"color: #267F99\">A<\/span> <span class=\"pl-k\">|<\/span> <span style=\"color: #267F99\">B<\/span>) {\r\n    <span style=\"color: #0000ff\">if<\/span> (<span style=\"color: #a31515\"><span class=\"pl-pds\">\"<\/span>a<span class=\"pl-pds\">\"<\/span><\/span> <span style=\"color: #0000ff\">in<\/span> <span class=\"pl-smi\">x<\/span>) {\r\n        <span style=\"color: #0000ff\">return<\/span> <span class=\"pl-smi\">x<\/span>.<span class=\"pl-smi\">a<\/span>;\r\n    }\r\n    <span style=\"color: #0000ff\">return<\/span> <span class=\"pl-smi\">x<\/span>.<span class=\"pl-smi\">b<\/span>;\r\n}<\/pre>\n<\/div>\n<h2 id=\"smarter-object-literal-inference\">Smarter object literal inference<\/h2>\n<p>There are certain patterns in JavaScript where users will omit properties so that all uses of those properties are effectively <code>undefined<\/code>.<\/p>\n<div class=\"highlight highlight-source-ts\">\n<pre><span style=\"color: #0000ff\">let<\/span> foo <span class=\"pl-k\">=<\/span> <span class=\"pl-smi\">someTest<\/span> <span class=\"pl-k\">?<\/span> { value: <span style=\"color: #09885A\">42<\/span> } <span class=\"pl-k\">:<\/span> {};<\/pre>\n<\/div>\n<p>TypeScript used seek the best common supertype between <code>{ value: number }<\/code> and <code>{}<\/code>, ending up with <code>{}<\/code>. While being technically correct, this wasn&#8217;t very useful.<\/p>\n<p>Starting with version 2.7, TypeScript now &#8220;normalizes&#8221; each object literal&#8217;s type to account for every property, inserting an optional property of type <code>undefined<\/code> on each object type, and unioning them together.<\/p>\n<p>From the above example, the new type of <code>foo<\/code> would be <code>{ value: number } | { value?: undefined }<\/code>. Combined with the ways TypeScript can narrow, this lets us write expressive code that TypeScript can still understand. As another example, take the following:<\/p>\n<div class=\"highlight highlight-source-ts\">\n<pre><span style=\"color: #148A14\">\/\/ Has type<\/span>\r\n<span style=\"color: #148A14\">\/\/  | { a: boolean, aData: number, b?: undefined }<\/span>\r\n<span style=\"color: #148A14\">\/\/  | { b: boolean, bData: string, a?: undefined }<\/span>\r\n<span style=\"color: #0000ff\">let<\/span> bar <span class=\"pl-k\">=<\/span> <span class=\"pl-c1\">Math<\/span>.<span class=\"pl-c1\">random<\/span>() <span class=\"pl-k\">&lt;<\/span> <span style=\"color: #09885A\">0.5<\/span> <span class=\"pl-k\">?<\/span>\r\n    { a: <span style=\"color: #0000ff\">true<\/span>, aData: <span style=\"color: #09885A\">100<\/span> } <span class=\"pl-k\">:<\/span>\r\n    { <span class=\"pl-smi\">b<\/span>: <span style=\"color: #0000ff\">true<\/span>, <span class=\"pl-smi\">bData<\/span>: <span style=\"color: #a31515\"><span class=\"pl-pds\">\"<\/span>hello<span class=\"pl-pds\">\"<\/span><\/span> };\r\n\r\n<span style=\"color: #0000ff\">if<\/span> (<span class=\"pl-smi\">bar<\/span>.<span class=\"pl-smi\">b<\/span>) {\r\n    <span style=\"color: #148A14\">\/\/ TypeScript now knows that 'bar' has the type<\/span>\r\n    <span style=\"color: #148A14\">\/\/<\/span>\r\n    <span style=\"color: #148A14\">\/\/   '{ b: boolean, bData: string, a?: undefined }'<\/span>\r\n    <span style=\"color: #148A14\">\/\/<\/span>\r\n    <span style=\"color: #148A14\">\/\/ so it knows that 'bData' is available.<\/span>\r\n    <span class=\"pl-smi\">bar<\/span>.<span class=\"pl-smi\">bData<\/span>.<span class=\"pl-c1\">toLowerCase<\/span>()\r\n}<\/pre>\n<\/div>\n<p>Here, TypeScript is able to narrow the type of <code>bar<\/code> based on checking its <code>b<\/code> property, allowing us to access the <code>bData<\/code> property.<\/p>\n<h2 id=\"breaking-changes\">Breaking Changes<\/h2>\n<p>This release brings some minor breaking changes:<\/p>\n<ul>\n<li>Tuples now have fixed numeric <code>length<\/code> properties.<\/li>\n<li><code>instanceof<\/code> and <code>in<\/code> now have slightly different narrowing behavior.<\/li>\n<li>Inferences from generic signatures now use base constraint types of type parameters instead of <code>any<\/code>.<\/li>\n<li><a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/API\/HTMLInputElement\/setSelectionRange\" rel=\"nofollow\">The <code>setSelectionRange<\/code> API<\/a> now only accepts <code>\"forward\" | \"backward\" | \"none\"<\/code>.<\/li>\n<li><code>allowSyntheticDefaultImports<\/code> no longer synthesizes default imports from TypeScript implementation files (i.e. <code>.ts<\/code> and <code>.tsx<\/code>).<\/li>\n<\/ul>\n<p>Additionally, as mentioned above, users with the <code>--strict<\/code> setting on will automatically be opted in to <code>--strictPropertyInitialization<\/code> which errors on properties which are not directly initialized on their declarations or in constructor bodies. While easy to opt out of by explicitly turning this check off, your code may be impacted.<\/p>\n<p>You can get a detailed look from our list of <a href=\"https:\/\/github.com\/Microsoft\/TypeScript\/issues?q=is%3Aissue+milestone%3A%22TypeScript+2.7%22+label%3A%22Breaking+Change%22+is%3Aclosed\">breaking changes issues for TypeScript 2.7<\/a> on GitHub, or keep track of general breaking changes on our <a href=\"https:\/\/github.com\/Microsoft\/TypeScript\/wiki\/Breaking-Changes\">Breaking Changes wiki page<\/a>.<\/p>\n<h2 id=\"whats-next\">What&#8217;s next?<\/h2>\n<p>We always try to bring more joy to the TypeScript experience. We hope this release continues the tradition of making you more productive and expressive to bring that joy to the core experience.<\/p>\n<p>Now that 2.7 is out, we&#8217;ve got some fantastic things in mind for TypeScript 2.8, including <a href=\"https:\/\/github.com\/Microsoft\/TypeScript\/pull\/21316\">conditional types<\/a>! While plans are still currently in flux, you can keep a close watch on <a href=\"https:\/\/github.com\/Microsoft\/TypeScript\/wiki\/Roadmap\">our roadmap<\/a> to get an idea of what&#8217;s on the TypeScript horizon.<\/p>\n<p>Let us know what you think of this release over <a href=\"http:\/\/twitter.com\/typescriptlang\/\" rel=\"nofollow\">on Twitter<\/a> or in the comments below, and feel free to report issues and suggestions filing <a href=\"https:\/\/github.com\/Microsoft\/TypeScript\/issues\">a GitHub issue<\/a>.<\/p>\n<p>Happy Hacking!<\/p>\n<\/article>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>Today we&#8217;re proud to announce the release of TypeScript 2.7! If you&#8217;re not familiar with TypeScript, it&#8217;s a language that brings optional static types to JavaScript by building on JavaScript itself. Running TypeScript code through its compiler emits clean readable JavaScript that runs on any browser, and can also make bleeding-edge ECMAScript features you write [&hellip;]<\/p>\n","protected":false},"author":381,"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-1285","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-typescript"],"acf":[],"blog_post_summary":"<p>Today we&#8217;re proud to announce the release of TypeScript 2.7! If you&#8217;re not familiar with TypeScript, it&#8217;s a language that brings optional static types to JavaScript by building on JavaScript itself. Running TypeScript code through its compiler emits clean readable JavaScript that runs on any browser, and can also make bleeding-edge ECMAScript features you write [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/typescript\/wp-json\/wp\/v2\/posts\/1285","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\/381"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/typescript\/wp-json\/wp\/v2\/comments?post=1285"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/typescript\/wp-json\/wp\/v2\/posts\/1285\/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=1285"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/typescript\/wp-json\/wp\/v2\/categories?post=1285"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/typescript\/wp-json\/wp\/v2\/tags?post=1285"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}