{"id":1681,"date":"2018-03-27T16:38:56","date_gmt":"2018-03-27T16:38:56","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/typescript\/?p=1395"},"modified":"2020-09-24T07:45:27","modified_gmt":"2020-09-24T15:45:27","slug":"announcing-typescript-2-8-2","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/typescript\/announcing-typescript-2-8-2\/","title":{"rendered":"Announcing TypeScript 2.8"},"content":{"rendered":"<p>TypeScript 2.8 is here and brings a few features that we think you&#8217;ll love <em>unconditionally<\/em>!<\/p>\n<p>If you&#8217;re not familiar with TypeScript, it&#8217;s a language that adds optional static types to JavaScript. Those static types help make guarantees about your code to avoid typos and other silly errors. They can also help provide nice things like code completions and easier project navigation thanks to tooling built around those types. When your code is run through the TypeScript compiler, you&#8217;re left with clean, readable, and standards-compliant JavaScript code, potentially rewritten to support much older browsers that only support ECMAScript 5 or even ECMAScript 3. To learn more about TypeScript, <a href=\"https:\/\/www.typescriptlang.org\/docs\/home.html\">check out our documentation<\/a>.<\/p>\n<p>If you can&#8217;t wait any longer, you can download TypeScript via <a href=\"https:\/\/www.nuget.org\/packages\/Microsoft.TypeScript.MSBuild\" rel=\"nofollow\">NuGet<\/a> or by running<\/p>\n<div class=\"highlight highlight-source-shell\">\n<pre>npm install -g typescript<\/pre>\n<\/div>\n<p>You can also get editor support for<\/p>\n<ul>\n<li><a href=\"https:\/\/gist.github.com\/DanielRosenwasser\/download.microsoft.com\/download\/6\/D\/8\/6D8381B0-03C1-4BD2-AE65-30FF0A4C62DA\/2.8.1-TS-release-dev14update3-20180323.2\/TypeScript_Dev14Full.exe\">Visual Studio 2015<\/a> (requires update 3)<\/li>\n<li><a href=\"http:\/\/download.microsoft.com\/download\/7\/0\/A\/70A6AC0E-8934-4396-A43E-445059F430EA\/2.8.1-TS-release-dev14update3-20180323.2\/TypeScript_SDK.exe\" rel=\"nofollow\">Visual Studio 2017<\/a> (requires 15.2 or later)<\/li>\n<li><a href=\"https:\/\/packagecontrol.io\/packages\/TypeScript\" rel=\"nofollow\">Sublime Text 3 via PackageControl<\/a><\/li>\n<li>Visual Studio Code with the next release, or <a href=\"https:\/\/code.visualstudio.com\/Docs\/languages\/typescript#_using-newer-typescript-versions\" rel=\"nofollow\">by following instructions here<\/a>.<\/li>\n<\/ul>\n<p><a href=\"https:\/\/github.com\/Microsoft\/TypeScript\/wiki\/TypeScript-Editor-Support\">Other editors<\/a> may have different update schedules, but should all have excellent TypeScript support soon as well.<\/p>\n<p>To get a quick glance at what we&#8217;re shipping in this release, we put this handy list together to navigate our blog post:<\/p>\n<ul>\n<li><a href=\"#conditional-types\">Conditional types<\/a><\/li>\n<li><a href=\"#declaration-only-emit\">Declaration-only emit<\/a><\/li>\n<li><a href=\"#jsx-pragma-comments\"><code style=\"color: #a31515;\">@jsx<\/code> pragma comments<\/a><\/li>\n<li><a href=\"#jsx-namespace-resolution\"><code style=\"color: #a31515;\">JSX<\/code> now resolved within factory functions<\/a><\/li>\n<li><a href=\"#granular-control-mapped-type-modifiers\">Granular control on mapped type modifiers<\/a><\/li>\n<li><a href=\"#organize-imports\">Organize imports<\/a><\/li>\n<li><a href=\"#uninitialized-properties\">Fixing uninitialized properties<\/a><\/li>\n<\/ul>\n<p>We also have some minor <a href=\"https:\/\/gist.github.com\/DanielRosenwasser\/6f1913483c5699155ad0777dc37a59b1#breaking-changes\">breaking changes<\/a> that you should keep in mind if upgrading.<\/p>\n<p>But otherwise, let&#8217;s look at what new features come with TypeScript 2.8!<\/p>\n<h2><a name=\"conditional-types\"><\/a>Conditional types<\/h2>\n<p>Conditional types are a new construct in TypeScript that allow us to choose types based on other types. They take the form<\/p>\n<div class=\"highlight highlight-source-ts\">\n<pre><span class=\"pl-c1\">A<\/span> <span class=\"pl-smi\">extends<\/span> <span class=\"pl-c1\">B<\/span> <span class=\"pl-k\">?<\/span> <span class=\"pl-c1\">C<\/span> <span class=\"pl-k\">:<\/span> <span class=\"pl-c1\">D<\/span><\/pre>\n<\/div>\n<p>where <code style=\"color: #a31515;\">A<\/code>, <code style=\"color: #a31515;\">B<\/code>, <code style=\"color: #a31515;\">C<\/code>, and <code style=\"color: #a31515;\">D<\/code> are all types. You should read that as &#8220;when the type <code style=\"color: #a31515;\">A<\/code> is assignable to <code style=\"color: #a31515;\">B<\/code>, then this type is <code style=\"color: #a31515;\">C<\/code>; otherwise, it&#8217;s <code style=\"color: #a31515;\">D<\/code>. If you&#8217;ve used conditional syntax in JavaScript, this will feel familiar to you.<\/p>\n<p>Let&#8217;s take two specific examples:<\/p>\n<div class=\"highlight highlight-source-ts\">\n<pre><span style=\"color: #0000ff;\">interface<\/span> <span style=\"color: #267f99;\">Animal<\/span> {\r\n    live()<span class=\"pl-k\">:<\/span> void;\r\n}\r\n<span style=\"color: #0000ff;\">interface<\/span> <span style=\"color: #267f99;\">Dog<\/span> <span style=\"color: #0000ff;\">extends<\/span> <span style=\"color: #267f99;\">Animal<\/span> {\r\n    woof()<span class=\"pl-k\">:<\/span> void;\r\n}\r\n\r\n<span style=\"color: #148a14;\">\/\/ Has type 'number'<\/span>\r\n<span style=\"color: #0000ff;\">type<\/span> <span style=\"color: #267f99;\">Foo<\/span> <span class=\"pl-k\">=<\/span> <span style=\"color: #267f99;\">Dog<\/span> <span class=\"pl-en\">extends<\/span> <span style=\"color: #267f99;\">Animal<\/span> ? <span style=\"color: #0000ff;\">number<\/span> : <span style=\"color: #0000ff;\">string<\/span>;\r\n\r\n<span style=\"color: #148a14;\">\/\/ Has type 'string'<\/span>\r\n<span style=\"color: #0000ff;\">type<\/span> <span style=\"color: #267f99;\">Bar<\/span> <span class=\"pl-k\">=<\/span> <span style=\"color: #267f99;\">RegExp<\/span> <span class=\"pl-en\">extends<\/span> <span style=\"color: #267f99;\">Dog<\/span> ? <span style=\"color: #0000ff;\">number<\/span> : <span style=\"color: #0000ff;\">string<\/span>;<\/pre>\n<\/div>\n<p>You might wonder why this is immediately useful. We can tell that <code style=\"color: #a31515;\">Foo<\/code> will be <code style=\"color: #a31515;\">number<\/code>, and <code style=\"color: #a31515;\">Bar<\/code> will be <code style=\"color: #a31515;\">string<\/code>, so we might as well write that out explicitly. But the real power of conditional types comes from using them with generics.<\/p>\n<p>For example, let&#8217;s take the following function:<\/p>\n<div class=\"highlight highlight-source-ts\">\n<pre><span style=\"color: #0000ff;\">interface<\/span> <span style=\"color: #267f99;\">Id<\/span> { id<span class=\"pl-k\">:<\/span> <span style=\"color: #0000ff;\">number<\/span>, <span style=\"color: #148a14;\">\/* other fields *\/<\/span> }\r\n<span style=\"color: #0000ff;\">interface<\/span> <span style=\"color: #267f99;\">Name<\/span> { name<span class=\"pl-k\">:<\/span> <span style=\"color: #0000ff;\">string<\/span>, <span style=\"color: #148a14;\">\/* other fields *\/<\/span> }\r\n\r\n<span style=\"color: #0000ff;\">declare<\/span> <span style=\"color: #0000ff;\">function<\/span> createLabel(<span class=\"pl-v\">id<\/span><span class=\"pl-k\">:<\/span> <span style=\"color: #0000ff;\">number<\/span>)<span class=\"pl-k\">:<\/span> <span style=\"color: #267f99;\">Id<\/span>;\r\n<span style=\"color: #0000ff;\">declare<\/span> <span style=\"color: #0000ff;\">function<\/span> createLabel(<span class=\"pl-v\">name<\/span><span class=\"pl-k\">:<\/span> <span style=\"color: #0000ff;\">string<\/span>)<span class=\"pl-k\">:<\/span> <span style=\"color: #267f99;\">Name<\/span>;\r\n<span style=\"color: #0000ff;\">declare<\/span> <span style=\"color: #0000ff;\">function<\/span> createLabel(<span class=\"pl-v\">name<\/span><span class=\"pl-k\">:<\/span> <span style=\"color: #0000ff;\">string<\/span> <span class=\"pl-k\">|<\/span> <span style=\"color: #0000ff;\">number<\/span>)<span class=\"pl-k\">:<\/span> <span style=\"color: #267f99;\">Id<\/span> <span class=\"pl-k\">|<\/span> <span style=\"color: #267f99;\">Name<\/span>;<\/pre>\n<\/div>\n<p>These overloads for <code style=\"color: #a31515;\">createLabel<\/code> describe a single JavaScript function that makes a choice based on the types of its inputs. Note two things:<\/p>\n<ol>\n<li>If a library has to make the same sort of choice over and over throughout its API, this becomes cumbersome.<\/li>\n<li>We have to create three overloads: one for each case when we&#8217;re <em>sure<\/em> of the type, and one for the most general case. For every other case we&#8217;d have to handle, the number of overloads would grow exponentially.<\/li>\n<\/ol>\n<p>Instead, we can use a conditional type to smoosh both of our overloads down to one, and create a type alias so that we can reuse that logic.<\/p>\n<div class=\"highlight highlight-source-ts\">\n<pre><span style=\"color: #0000ff;\">type<\/span> <span style=\"color: #267f99;\">IdOrName<\/span>&lt;<span style=\"color: #267f99;\">T<\/span> <span style=\"color: #0000ff;\">extends<\/span> <span style=\"color: #0000ff;\">number<\/span> <span class=\"pl-k\">|<\/span> <span style=\"color: #0000ff;\">string<\/span>&gt; <span class=\"pl-k\">=<\/span>\r\n    <span style=\"color: #267f99;\">T<\/span> <span class=\"pl-en\">extends<\/span> <span style=\"color: #0000ff;\">number<\/span> ? <span style=\"color: #267f99;\">Id<\/span> : <span style=\"color: #267f99;\">Name<\/span>;\r\n\r\n<span style=\"color: #0000ff;\">declare<\/span> <span style=\"color: #0000ff;\">function<\/span> createLabel&lt;<span style=\"color: #267f99;\">T<\/span> <span style=\"color: #0000ff;\">extends<\/span> <span style=\"color: #0000ff;\">number<\/span> <span class=\"pl-k\">|<\/span> <span style=\"color: #0000ff;\">string<\/span>&gt;(<span class=\"pl-v\">idOrName<\/span><span class=\"pl-k\">:<\/span> <span style=\"color: #267f99;\">T<\/span>)<span class=\"pl-k\">:<\/span>\r\n    <span style=\"color: #267f99;\">T<\/span> <span class=\"pl-en\">extends<\/span> <span style=\"color: #0000ff;\">number<\/span> ? <span style=\"color: #267f99;\">Id<\/span> : <span style=\"color: #267f99;\">Name<\/span>;\r\n\r\n<span style=\"color: #0000ff;\">let<\/span> a <span class=\"pl-k\">=<\/span> <span class=\"pl-en\">createLabel<\/span>(<span style=\"color: #a31515;\"><span class=\"pl-pds\">\"<\/span>typescript<span class=\"pl-pds\">\"<\/span><\/span>);   <span style=\"color: #148a14;\">\/\/ Name<\/span>\r\n<span style=\"color: #0000ff;\">let<\/span> b <span class=\"pl-k\">=<\/span> <span class=\"pl-en\">createLabel<\/span>(<span style=\"color: #09885a;\">2.8<\/span>);            <span style=\"color: #148a14;\">\/\/ Id<\/span>\r\n<span style=\"color: #0000ff;\">let<\/span> c <span class=\"pl-k\">=<\/span> <span class=\"pl-en\">createLabel<\/span>(<span style=\"color: #a31515;\"><span class=\"pl-pds\">\"<\/span><span class=\"pl-pds\">\"<\/span><\/span> <span style=\"color: #0000ff;\">as<\/span> any);      <span style=\"color: #148a14;\">\/\/ Id | Name<\/span>\r\n<span style=\"color: #0000ff;\">let<\/span> d <span class=\"pl-k\">=<\/span> <span class=\"pl-en\">createLabel<\/span>(<span style=\"color: #a31515;\"><span class=\"pl-pds\">\"<\/span><span class=\"pl-pds\">\"<\/span><\/span> <span style=\"color: #0000ff;\">as<\/span> never);    <span style=\"color: #148a14;\">\/\/ never<\/span><\/pre>\n<\/div>\n<p>Just like how JavaScript can make decisions at runtime based on the characteristics of a value, conditional types let TypeScript make decisions in the type system based on the characteristics of other types.<\/p>\n<p>As another example, we could also write a type called <code style=\"color: #a31515;\">Flatten<\/code> that flattens array types to their element types, but leaves them alone otherwise:<\/p>\n<div class=\"highlight highlight-source-ts\">\n<pre><span style=\"color: #148a14;\">\/\/ If we have an array, get the type when we index with a 'number'.<\/span>\r\n<span style=\"color: #148a14;\">\/\/ Otherwise, leave the type alone.<\/span>\r\n<span style=\"color: #0000ff;\">type<\/span> <span style=\"color: #267f99;\">Flatten<\/span>&lt;<span style=\"color: #267f99;\">T<\/span>&gt; <span class=\"pl-k\">=<\/span> <span style=\"color: #267f99;\">T<\/span> <span class=\"pl-en\">extends<\/span> any[] ? <span style=\"color: #267f99;\">T<\/span>[<span style=\"color: #0000ff;\">number<\/span>] : <span style=\"color: #267f99;\">T<\/span>;<\/pre>\n<\/div>\n<h3>Inferring within conditional types<\/h3>\n<p>Conditional types also provide us with a way to infer from types we compare against in the true branch using the <code style=\"color: #a31515;\">infer<\/code> keyword. For example, we could have inferred the element type in <code style=\"color: #a31515;\">Flatten<\/code> instead of fetching it out manually:<\/p>\n<div class=\"highlight highlight-source-ts\">\n<pre><span style=\"color: #148a14;\">\/\/ We also could also have used '(infer U)[]' instead of 'Array&lt;infer U&gt;'<\/span>\r\n<span style=\"color: #0000ff;\">type<\/span> <span style=\"color: #267f99;\">Flatten<\/span>&lt;<span style=\"color: #267f99;\">T<\/span>&gt; <span class=\"pl-k\">=<\/span> <span style=\"color: #267f99;\">T<\/span> <span class=\"pl-en\">extends<\/span> <span style=\"color: #267f99;\">Array<\/span>&lt;<span class=\"pl-en\">infer<\/span> <span style=\"color: #267f99;\">U<\/span>&gt; ? <span style=\"color: #267f99;\">U<\/span> : <span style=\"color: #267f99;\">T<\/span>;<\/pre>\n<\/div>\n<p>Here, we&#8217;ve declaratively introduced a new generic type variable named <code style=\"color: #a31515;\">U<\/code> instead of specifying how to retrieve the element type of <code style=\"color: #a31515;\">T<\/code>. This frees us from having to think about how to get the types we&#8217;re interested in.<\/p>\n<h3>Distributing on unions with conditionals<\/h3>\n<p>When conditional types act on a single type parameter, they distribute across unions. So in the following example, <code style=\"color: #a31515;\">Bar<\/code> has the type <code style=\"color: #a31515;\">string[] | number[]<\/code> because <code style=\"color: #a31515;\">Foo<\/code> is applied to the union type <code style=\"color: #a31515;\">string | number<\/code>.<\/p>\n<div class=\"highlight highlight-source-ts\">\n<pre><span style=\"color: #0000ff;\">type<\/span> <span style=\"color: #267f99;\">Foo<\/span>&lt;<span style=\"color: #267f99;\">T<\/span>&gt; <span class=\"pl-k\">=<\/span> <span style=\"color: #267f99;\">T<\/span> <span class=\"pl-en\">extends<\/span> any ? <span style=\"color: #267f99;\">T<\/span>[] : never;\r\n\r\n<span style=\"color: #148a14;\">\/**<\/span>\r\n<span style=\"color: #148a14;\"> * Foo distributes on 'string | number' to the type<\/span>\r\n<span style=\"color: #148a14;\"> *<\/span>\r\n<span style=\"color: #148a14;\"> *    (string extends any ? string[] : never) |<\/span>\r\n<span style=\"color: #148a14;\"> *    (number extends any ? number[] : never)<\/span>\r\n<span style=\"color: #148a14;\"> * <\/span>\r\n<span style=\"color: #148a14;\"> * which boils down to<\/span>\r\n<span style=\"color: #148a14;\"> *<\/span>\r\n<span style=\"color: #148a14;\"> *    string[] | number[]<\/span>\r\n<span style=\"color: #148a14;\"> *\/<\/span>\r\n<span style=\"color: #0000ff;\">type<\/span> <span style=\"color: #267f99;\">Bar<\/span> <span class=\"pl-k\">=<\/span> <span style=\"color: #267f99;\">Foo<\/span>&lt;<span style=\"color: #0000ff;\">string<\/span> <span class=\"pl-k\">|<\/span> <span style=\"color: #0000ff;\">number<\/span>&gt;;<\/pre>\n<\/div>\n<p>In case you ever need to avoid distributing on unions, you can surround each side of the <code style=\"color: #a31515;\">extends<\/code> keyword with square brackets:<\/p>\n<div class=\"highlight highlight-source-ts\">\n<pre><span style=\"color: #0000ff;\">type<\/span> <span style=\"color: #267f99;\">Foo<\/span>&lt;<span style=\"color: #267f99;\">T<\/span>&gt; <span class=\"pl-k\">=<\/span> [<span style=\"color: #267f99;\">T<\/span>] <span class=\"pl-en\">extends<\/span> [any] ? <span style=\"color: #267f99;\">T<\/span>[] : never;\r\n\r\n<span style=\"color: #148a14;\">\/\/ Boils down to Array&lt;string | number&gt;<\/span>\r\n<span style=\"color: #0000ff;\">type<\/span> <span style=\"color: #267f99;\">Bar<\/span> <span class=\"pl-k\">=<\/span> <span style=\"color: #267f99;\">Foo<\/span>&lt;<span style=\"color: #0000ff;\">string<\/span> <span class=\"pl-k\">|<\/span> <span style=\"color: #0000ff;\">number<\/span>&gt;;<\/pre>\n<\/div>\n<p>While conditional types can be a little intimidating at first, we believe they&#8217;ll bring a ton of flexibility for moments when you need to push the type system a little further to get accurate types.<\/p>\n<h3>New built-in helpers<\/h3>\n<p>TypeScript 2.8 provides several new type aliases in <code style=\"color: #a31515;\">lib.d.ts<\/code> that take advantage of conditional types:<\/p>\n<div class=\"highlight highlight-source-ts\">\n<pre><span style=\"color: #148a14;\">\/\/ These are all now built into lib.d.ts!<\/span>\r\n\r\n<span style=\"color: #148a14;\">\/**<\/span>\r\n<span style=\"color: #148a14;\"> * Exclude from T those types that are assignable to U<\/span>\r\n<span style=\"color: #148a14;\"> *\/<\/span>\r\n<span style=\"color: #0000ff;\">type<\/span> <span style=\"color: #267f99;\">Exclude<\/span>&lt;<span style=\"color: #267f99;\">T<\/span>, <span style=\"color: #267f99;\">U<\/span>&gt; <span class=\"pl-k\">=<\/span> <span style=\"color: #267f99;\">T<\/span> <span class=\"pl-en\">extends<\/span> <span style=\"color: #267f99;\">U<\/span> ? never : <span style=\"color: #267f99;\">T<\/span>;\r\n\r\n<span style=\"color: #148a14;\">\/**<\/span>\r\n<span style=\"color: #148a14;\"> * Extract from T those types that are assignable to U<\/span>\r\n<span style=\"color: #148a14;\"> *\/<\/span>\r\n<span style=\"color: #0000ff;\">type<\/span> <span style=\"color: #267f99;\">Extract<\/span>&lt;<span style=\"color: #267f99;\">T<\/span>, <span style=\"color: #267f99;\">U<\/span>&gt; <span class=\"pl-k\">=<\/span> <span style=\"color: #267f99;\">T<\/span> <span class=\"pl-en\">extends<\/span> <span style=\"color: #267f99;\">U<\/span> ? <span style=\"color: #267f99;\">T<\/span> : never;\r\n\r\n<span style=\"color: #148a14;\">\/**<\/span>\r\n<span style=\"color: #148a14;\"> * Exclude null and undefined from T<\/span>\r\n<span style=\"color: #148a14;\"> *\/<\/span>\r\n<span style=\"color: #0000ff;\">type<\/span> <span style=\"color: #267f99;\">NonNullable<\/span>&lt;<span style=\"color: #267f99;\">T<\/span>&gt; <span class=\"pl-k\">=<\/span> <span style=\"color: #267f99;\">T<\/span> <span class=\"pl-en\">extends<\/span> null <span class=\"pl-k\">|<\/span> undefined ? never : <span style=\"color: #267f99;\">T<\/span>;\r\n\r\n<span style=\"color: #148a14;\">\/**<\/span>\r\n<span style=\"color: #148a14;\"> * Obtain the return type of a function type<\/span>\r\n<span style=\"color: #148a14;\"> *\/<\/span>\r\n<span style=\"color: #0000ff;\">type<\/span> <span style=\"color: #267f99;\">ReturnType<\/span>&lt;<span style=\"color: #267f99;\">T<\/span> <span style=\"color: #0000ff;\">extends<\/span> (<span class=\"pl-k\">...<\/span><span class=\"pl-v\">args<\/span><span class=\"pl-k\">:<\/span> any[]) <span class=\"pl-k\">=&gt;<\/span> any&gt; <span class=\"pl-k\">=<\/span> <span style=\"color: #267f99;\">T<\/span> <span class=\"pl-en\">extends<\/span> (<span class=\"pl-k\">...<\/span><span class=\"pl-v\">args<\/span><span class=\"pl-k\">:<\/span> any[]) <span class=\"pl-k\">=&gt;<\/span> <span class=\"pl-en\">infer<\/span> <span style=\"color: #267f99;\">R<\/span> ? <span style=\"color: #267f99;\">R<\/span> : any;\r\n\r\n<span style=\"color: #148a14;\">\/**<\/span>\r\n<span style=\"color: #148a14;\"> * Obtain the return type of a constructor function type<\/span>\r\n<span style=\"color: #148a14;\"> *\/<\/span>\r\n<span style=\"color: #0000ff;\">type<\/span> <span style=\"color: #267f99;\">InstanceType<\/span>&lt;<span style=\"color: #267f99;\">T<\/span> <span style=\"color: #0000ff;\">extends<\/span> <span style=\"color: #0000ff;\">new<\/span> (<span class=\"pl-k\">...<\/span><span class=\"pl-v\">args<\/span><span class=\"pl-k\">:<\/span> any[]) <span class=\"pl-k\">=&gt;<\/span> any&gt; <span class=\"pl-k\">=<\/span> <span style=\"color: #267f99;\">T<\/span> <span class=\"pl-en\">extends<\/span> <span style=\"color: #0000ff;\">new<\/span> (<span class=\"pl-k\">...<\/span><span class=\"pl-v\">args<\/span><span class=\"pl-k\">:<\/span> any[]) <span class=\"pl-k\">=&gt;<\/span> <span class=\"pl-en\">infer<\/span> <span style=\"color: #267f99;\">R<\/span> ? <span style=\"color: #267f99;\">R<\/span> : any;<\/pre>\n<\/div>\n<p>While <code style=\"color: #a31515;\">NonNullable<\/code>, <code style=\"color: #a31515;\">ReturnType<\/code>, and <code style=\"color: #a31515;\">InstanceType<\/code> are relatively self-explanatory, <code style=\"color: #a31515;\">Exclude<\/code> and <code style=\"color: #a31515;\">Extract<\/code> are a bit more interesting.<\/p>\n<p><code style=\"color: #a31515;\">Extract<\/code> selects types from its first argument that are assignable to its second argument:<\/p>\n<div class=\"highlight highlight-source-ts\">\n<pre><span style=\"color: #148a14;\">\/\/ string[] | number[]<\/span>\r\n<span style=\"color: #0000ff;\">type<\/span> <span style=\"color: #267f99;\">Foo<\/span> <span class=\"pl-k\">=<\/span> <span style=\"color: #267f99;\">Extract<\/span>&lt;<span style=\"color: #0000ff;\">boolean<\/span> <span class=\"pl-k\">|<\/span> <span style=\"color: #0000ff;\">string<\/span>[] <span class=\"pl-k\">|<\/span> <span style=\"color: #0000ff;\">number<\/span>[], any[]&gt;;<\/pre>\n<\/div>\n<p><code style=\"color: #a31515;\">Exclude<\/code> does the opposite; it removes types from its first argument that are not assignable to its second:<\/p>\n<div class=\"highlight highlight-source-ts\">\n<pre><span style=\"color: #148a14;\">\/\/ boolean<\/span>\r\n<span style=\"color: #0000ff;\">type<\/span> <span style=\"color: #267f99;\">Bar<\/span> <span class=\"pl-k\">=<\/span> <span style=\"color: #267f99;\">Exclude<\/span>&lt;<span style=\"color: #0000ff;\">boolean<\/span> <span class=\"pl-k\">|<\/span> <span style=\"color: #0000ff;\">string<\/span>[] <span class=\"pl-k\">|<\/span> <span style=\"color: #0000ff;\">number<\/span>[], any[]&gt;;<\/pre>\n<\/div>\n<h2><a name=\"declaration-only-emit\"><\/a>Declaration-only emit<\/h2>\n<p>Thanks to <a href=\"https:\/\/github.com\/Microsoft\/TypeScript\/pull\/20735\">a pull request<\/a> from <a href=\"https:\/\/github.com\/nojvek\">Manoj Patel<\/a>, TypeScript now features an <code style=\"color: #a31515;\">--emitDeclarationOnly<\/code> flag which can be used for cases when you have an alternative build step for emitting JavaScript files, but need to emit declaration files separately. Under this mode no JavaScript files nor sourcemap files will be generated; just <code style=\"color: #a31515;\">.d.ts<\/code> files that can be used for library consumers.<\/p>\n<p>One use-case for this is when using alternate compilers for TypeScript such as Babel 7. For an example of repositories taking advantage of this flag, check out <a href=\"https:\/\/github.com\/FormidableLabs\/urql\/tree\/ce9fb3cc02c8530e0b70cfb31d09690dab8b02dc\">urql from Formidable Labs<\/a>, or take a look at <a href=\"https:\/\/github.com\/Microsoft\/TypeScript-Babel-Starter\">our Babel starter repo<\/a>.<\/p>\n<h2><a name=\"jsx-pragma-comments\"><\/a><code style=\"color: #a31515; font-size: 29px;\">@jsx<\/code> pragma comments<\/h2>\n<p>Typically, users of JSX expect to have their JSX tags rewritten to <code style=\"color: #a31515;\">React.createElement<\/code>. However, if you&#8217;re using libraries that have a React-like factory API, such as Preact, Stencil, Inferno, Cycle, and others, you might want to tweak that emit slightly.<\/p>\n<p>Previously, TypeScript only allowed users to control the emit for JSX at a global level using the <code style=\"color: #a31515;\">jsxFactory<\/code> option (as well as the deprecated <code style=\"color: #a31515;\">reactNamespace<\/code> option). However, if you needed to mix any of these libraries in the same application, you&#8217;d have been out of luck using JSX for both.<\/p>\n<p>Luckily, TypeScript 2.8 now allows you to set your JSX factory on a file-by-file basis by adding an <code style=\"color: #a31515;\">\/\/ @jsx<\/code> comment at the top of your file. If you&#8217;ve used the same functionality in Babel, this should look slightly familiar.<\/p>\n<div class=\"highlight highlight-source-ts\">\n<pre><span style=\"color: #148a14;\">\/** @jsx dom *\/<\/span>\r\n<span style=\"color: #0000ff;\">import<\/span> { <span class=\"pl-smi\">dom<\/span> } <span style=\"color: #0000ff;\">from<\/span> <span style=\"color: #a31515;\"><span class=\"pl-pds\">\"<\/span>.\/renderer<span class=\"pl-pds\">\"<\/span><\/span>\r\n&lt;<span class=\"pl-en\">h<\/span>&gt;&lt;\/<span class=\"pl-en\">h<\/span>&gt;<\/pre>\n<\/div>\n<p>The above sample imports a function named <code style=\"color: #a31515;\">dom<\/code>, and uses the <code style=\"color: #a31515;\">jsx<\/code> pragma to select <code style=\"color: #a31515;\">dom<\/code> as the factory for all JSX expressions in the file. TypeScript 2.8 will rewrite it to the following when compiling to CommonJS and ES5:<\/p>\n<div class=\"highlight highlight-source-js\">\n<pre><span style=\"color: #0000ff;\">var<\/span> renderer_1 <span class=\"pl-k\">=<\/span> require(<span style=\"color: #a31515;\"><span class=\"pl-pds\">\"<\/span>.\/renderer<span class=\"pl-pds\">\"<\/span><\/span>);\r\n<span class=\"pl-smi\">renderer_1<\/span>.<span class=\"pl-en\">dom<\/span>(<span style=\"color: #a31515;\"><span class=\"pl-pds\">\"<\/span>h<span class=\"pl-pds\">\"<\/span><\/span>, null);<\/pre>\n<\/div>\n<h2><a name=\"jsx-namespace-resolution\"><\/a><code style=\"color: #a31515; font-size: 29px;\">JSX<\/code> is resolved via the JSX Factory<\/h2>\n<p>Currently, when TypeScript uses JSX, it looks up a global <code style=\"color: #a31515;\">JSX<\/code> namespace to look up certain types (e.g. &#8220;what&#8217;s the type of a JSX component?&#8221;). In TypeScript 2.8, the compiler will try to look up the <code style=\"color: #a31515;\">JSX<\/code> namespace based on the location of your JSX factory. For example, if your JSX factory is <code style=\"color: #a31515;\">React.createElement<\/code>, TypeScript will try to first resolve <code style=\"color: #a31515;\">React.JSX<\/code>, and then resolve <code style=\"color: #a31515;\">JSX<\/code> from within the current scope.<\/p>\n<p>This can be helpful when mixing and matching different libraries (e.g. React and Preact) or different versions of a specific library (e.g. React 14 and React 16), as placing the JSX namespace in the global scope can cause issues.<\/p>\n<p>Going forward, we recommend that new JSX-oriented libraries avoid placing <code style=\"color: #a31515;\">JSX<\/code> in the global scope, and instead export it from the same location as the respective factory function. However, for backward compatibility, TypeScript will continue falling back to the global scope when necessary.<\/p>\n<h2><a name=\"granular-control-mapped-type-modifiers\"><\/a> Granular control on mapped type modifiers<\/h2>\n<p>TypeScript&#8217;s mapped object types are an incredibly powerful construct. One handy feature is that they allow users to create new types that have modifiers set for all their properties. For example, the following type creates a new type based on <code style=\"color: #a31515;\">T<\/code> and where every property in <code style=\"color: #a31515;\">T<\/code> becomes <code style=\"color: #a31515;\">readonly<\/code> and optional (<code style=\"color: #a31515;\">?<\/code>).<\/p>\n<div class=\"highlight highlight-source-ts\">\n<pre><span style=\"color: #148a14;\">\/\/ Creates a type with all the properties in T,<\/span>\r\n<span style=\"color: #148a14;\">\/\/ but marked both readonly and optional.<\/span>\r\n<span style=\"color: #0000ff;\">type<\/span> <span style=\"color: #267f99;\">ReadonlyAndPartial<\/span>&lt;<span style=\"color: #267f99;\">T<\/span>&gt; <span class=\"pl-k\">=<\/span> {\r\n    <span style=\"color: #0000ff;\">readonly<\/span> [<span style=\"color: #267f99;\">P<\/span> <span style=\"color: #0000ff;\">in<\/span> <span style=\"color: #0000ff;\">keyof<\/span> <span style=\"color: #267f99;\">T<\/span>]<span class=\"pl-k\">?<\/span><span class=\"pl-k\">:<\/span> <span style=\"color: #267f99;\">T<\/span>[<span style=\"color: #267f99;\">P<\/span>]\r\n}<\/pre>\n<\/div>\n<p>So mapped object types can <em>add<\/em> modifiers, but up until this point, there was no way to <em>remove<\/em> modifiers from <code style=\"color: #a31515;\">T<\/code>.<\/p>\n<p>TypeScript 2.8 provides a new syntax for removing modifiers in mapped types with the <code style=\"color: #a31515;\">-<\/code> operator, and a new more explicit syntax for adding modifiers with the <code style=\"color: #a31515;\">+<\/code> operator. For example,<\/p>\n<div class=\"highlight highlight-source-ts\">\n<pre><span style=\"color: #0000ff;\">type<\/span> <span style=\"color: #267f99;\">Mutable<\/span>&lt;<span style=\"color: #267f99;\">T<\/span>&gt; <span class=\"pl-k\">=<\/span> {\r\n    -<span style=\"color: #0000ff;\">readonly<\/span> [<span style=\"color: #267f99;\">P<\/span> <span style=\"color: #0000ff;\">in<\/span> <span style=\"color: #0000ff;\">keyof<\/span> <span style=\"color: #267f99;\">T<\/span>]<span class=\"pl-k\">:<\/span> <span style=\"color: #267f99;\">T<\/span>[<span style=\"color: #267f99;\">P<\/span>]\r\n}\r\n\r\n<span style=\"color: #0000ff;\">interface<\/span> <span style=\"color: #267f99;\">Foo<\/span> {\r\n    <span style=\"color: #0000ff;\">readonly<\/span> abc<span class=\"pl-k\">:<\/span> <span style=\"color: #0000ff;\">number<\/span>;\r\n    def<span class=\"pl-k\">?<\/span><span class=\"pl-k\">:<\/span> <span style=\"color: #0000ff;\">string<\/span>;\r\n}\r\n\r\n<span style=\"color: #148a14;\">\/\/ 'abc' is no longer read-only, but 'def' is still optional.<\/span>\r\n<span style=\"color: #0000ff;\">type<\/span> <span style=\"color: #267f99;\">TotallyMutableFoo<\/span> <span class=\"pl-k\">=<\/span> <span style=\"color: #267f99;\">Mutable<\/span>&lt;<span style=\"color: #267f99;\">Foo<\/span>&gt;<\/pre>\n<\/div>\n<p>In the above, <code style=\"color: #a31515;\">Mutable<\/code> removes <code style=\"color: #a31515;\">readonly<\/code> from each property of the type that it maps over.<\/p>\n<p>Similarly, TypeScript now provides a new <code style=\"color: #a31515;\">Required<\/code> type in <code style=\"color: #a31515;\">lib.d.ts<\/code> that removes optionality from each property:<\/p>\n<div class=\"highlight highlight-source-ts\">\n<pre><span style=\"color: #148a14;\">\/**<\/span>\r\n<span style=\"color: #148a14;\"> * Make all properties in T required<\/span>\r\n<span style=\"color: #148a14;\"> *\/<\/span>\r\n<span style=\"color: #0000ff;\">type<\/span> <span style=\"color: #267f99;\">Required<\/span>&lt;<span style=\"color: #267f99;\">T<\/span>&gt; <span class=\"pl-k\">=<\/span> {\r\n    [<span style=\"color: #267f99;\">P<\/span> <span style=\"color: #0000ff;\">in<\/span> <span style=\"color: #0000ff;\">keyof<\/span> <span style=\"color: #267f99;\">T<\/span>]-?<span class=\"pl-k\">:<\/span> <span style=\"color: #267f99;\">T<\/span>[<span style=\"color: #267f99;\">P<\/span>];\r\n}<\/pre>\n<\/div>\n<p>The <code style=\"color: #a31515;\">+<\/code> operator can be handy when you want to call out that a mapped type is adding modifiers. For example, our <code style=\"color: #a31515;\">ReadonlyAndPartial<\/code> from above could be defined as follows:<\/p>\n<div class=\"highlight highlight-source-ts\">\n<pre><span style=\"color: #0000ff;\">type<\/span> <span style=\"color: #267f99;\">ReadonlyAndPartial<\/span>&lt;<span style=\"color: #267f99;\">T<\/span>&gt; <span class=\"pl-k\">=<\/span> {\r\n    +<span style=\"color: #0000ff;\">readonly<\/span> [<span style=\"color: #267f99;\">P<\/span> <span style=\"color: #0000ff;\">in<\/span> <span style=\"color: #0000ff;\">keyof<\/span> <span style=\"color: #267f99;\">T<\/span>]+?<span class=\"pl-k\">:<\/span> <span style=\"color: #267f99;\">T<\/span>[<span style=\"color: #267f99;\">P<\/span>];\r\n}<\/pre>\n<\/div>\n<h2><a name=\"organize-imports\"><\/a>Organize imports<\/h2>\n<p>TypeScript&#8217;s language service now provides functionality to organize imports. This feature will remove any unused imports, sort existing imports by file paths, and sort named imports as well.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/typescript\/wp-content\/uploads\/sites\/11\/2018\/03\/organizeImports-2.8.gif\" \/><\/p>\n<h2><a name=\"uninitialized-properties\"><\/a>Fixing uninitialized properties<\/h2>\n<p>TypeScript 2.7 introduced extra checking for uninitialized properties in classes. Thanks to <a href=\"https:\/\/github.com\/Microsoft\/TypeScript\/pull\/21528\">a pull request<\/a> by <a href=\"https:\/\/github.com\/Kingwl\">Wenlu Wang<\/a> TypeScript 2.8 brings some helpful quick fixes to make it easier to add to your codebase.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/typescript\/wp-content\/uploads\/sites\/11\/2018\/03\/uninitializedPropFixes-2.8.gif\" \/><\/p>\n<h2><a name=\"conditional-types\"><\/a>Breaking changes<\/h2>\n<h3>Unused type parameters are checked under <code style=\"color: #a31515; font-size: 26px;\">--noUnusedParameters<\/code><\/h3>\n<p>Unused type parameters were previously reported under <code style=\"color: #a31515;\">--noUnusedLocals<\/code>, but are now instead reported under <code style=\"color: #a31515;\">--noUnusedParameters<\/code>.<\/p>\n<h3><code style=\"color: #a31515; font-size: 26px;\">HTMLObjectElement<\/code> no longer has an <code style=\"color: #a31515; font-size: 26px;\">alt<\/code> attribute<\/h3>\n<p>Such behavior is not covered by the WHATWG standard.<\/p>\n<h2>What&#8217;s next?<\/h2>\n<p>We hope that TypeScript 2.8 pushes the envelope further to provide a type system that can truly represent the nature of JavaScript as a language. With that, we believe we can provide you with an experience that continues to make you more productive and happier as you code.<\/p>\n<p>Over the next few weeks, we&#8217;ll have a clearer picture of what&#8217;s in store for TypeScript 2.9, but as always, you can keep an eye on <a href=\"https:\/\/github.com\/Microsoft\/TypeScript\/wiki\/Roadmap\">the TypeScript roadmap<\/a> to see what we&#8217;re working on for our next release. You can also try out our nightly releases to try out the future today! For example, generic JSX elements are already out in TypeScript&#8217;s recent nightly releases!<\/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","protected":false},"excerpt":{"rendered":"<p>TypeScript 2.8 is here and brings a few features that we think you&#8217;ll love unconditionally! If you&#8217;re not familiar with TypeScript, it&#8217;s a language that adds optional static types to JavaScript. Those static types help make guarantees about your code to avoid typos and other silly errors. They can also help provide nice things like [&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-1681","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-typescript"],"acf":[],"blog_post_summary":"<p>TypeScript 2.8 is here and brings a few features that we think you&#8217;ll love unconditionally! If you&#8217;re not familiar with TypeScript, it&#8217;s a language that adds optional static types to JavaScript. Those static types help make guarantees about your code to avoid typos and other silly errors. They can also help provide nice things like [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/typescript\/wp-json\/wp\/v2\/posts\/1681","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=1681"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/typescript\/wp-json\/wp\/v2\/posts\/1681\/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=1681"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/typescript\/wp-json\/wp\/v2\/categories?post=1681"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/typescript\/wp-json\/wp\/v2\/tags?post=1681"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}