<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Nicholas Jamieson</title>
    <description>The latest articles on DEV Community by Nicholas Jamieson (@cartant).</description>
    <link>https://dev.to/cartant</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F35774%2Feaa80151-10ab-4d0f-820d-22aa9f662d28.png</url>
      <title>DEV Community: Nicholas Jamieson</title>
      <link>https://dev.to/cartant</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/cartant"/>
    <language>en</language>
    <item>
      <title>How to Find Projects Using GitHub Stars</title>
      <dc:creator>Nicholas Jamieson</dc:creator>
      <pubDate>Tue, 25 Feb 2020 21:05:33 +0000</pubDate>
      <link>https://dev.to/cartant/how-to-find-projects-using-github-stars-36l4</link>
      <guid>https://dev.to/cartant/how-to-find-projects-using-github-stars-36l4</guid>
      <description>&lt;p&gt;&lt;em&gt;This article was originally published on &lt;a href="https://ncjamieson.com/github-stars/"&gt;my blog&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;




&lt;p&gt;It's pretty common to refer to a GitHub project's star count. For example, at the moment, React has 144,162 stars, Angular has 58,093 and Vue has 157,325.&lt;/p&gt;

&lt;p&gt;Those are some big numbers, but what do they mean? Would you choose a framework based on star counts? I wouldn't. However, I do think GitHub stars are useful and I use them every day. And that's what this post is about.&lt;/p&gt;

&lt;p&gt;GitHub has some pseudo-social features that not everyone seems to use. Well, I'm pretty sure that some people don't, because several of the developers I've spoken with recently didn't know about or use these features.&lt;/p&gt;

&lt;p&gt;It's possible to follow other people on GitHub: you visit their profile and click the follow button. They are then added to your following list and you're added to their followers list.&lt;/p&gt;

&lt;p&gt;Once you have followed some people on Github, things get interesting — and useful — when you visit your dashboard. Your dashboard is what you see if you navigate to &lt;a href="https://github.com/"&gt;github.com/&lt;/a&gt; — when you're logged in, of course.&lt;/p&gt;

&lt;p&gt;The middle of the dashboard shows your 'Recent activity': your comments, issues, PRs, reviews, etc. Which is somewhat useful, but I deal with most of that stuff via email notifications. The interesting bit is below that: 'All activity'.&lt;/p&gt;

&lt;p&gt;The 'All activity' section shows you some of the things that the people you are following have been up to. The section includes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;repos they've created;&lt;/li&gt;
&lt;li&gt;repos they've made public;&lt;/li&gt;
&lt;li&gt;repos they've forked;&lt;/li&gt;
&lt;li&gt;repos they've pushed to — if you are watching the repo;&lt;/li&gt;
&lt;li&gt;repos they've starred; and&lt;/li&gt;
&lt;li&gt;people they've followed.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It's interesting to see people's activity — particularly if they've just created a new project — but the most useful inclusion, for me, are the repos that people have starred. It's a great way to find out about new packages. It's often that case the that people you've chosen to follow have similar interests and are solving the same kinds of problems that you are, so repos that they've decided to star are quite likely to be of use — or, at least, of interest — to you. Most of my package discoveries are made this way.&lt;/p&gt;

&lt;p&gt;The relationship between followers and stars is presented in another part GitHub's user interface, too. When you click a repo's star count, it navigates to a page that gives you a paginated view of the repo's stargazers — the people who starred it. On that page, there are two tabs that separate said stargazers into the people you know — that is, the people you follow — and everyone else.&lt;/p&gt;

&lt;p&gt;For me, this is really useful. When I'm trying to decide which package to use, I'll take a peek to see whether or not someone I know has starred its repo. If one package has no stars from people I know and another has several, it's likely that I'll choose the latter. There are other factors, of course, but this is useful information.&lt;/p&gt;

&lt;p&gt;GitHub stars are also useful as bookmarks. It's often the case that I star something because it looks interesting and I anticipate its being useful in the future. Fortunately, the list of starred repos can be filtered, so when I'm looking for some CLI-related package that I can remember starring I can filter the list using &lt;a href="https://github.com/cartant?tab=stars&amp;amp;utf8=%E2%9C%93&amp;amp;q=&amp;amp;q=cli"&gt;'cli'&lt;/a&gt; as the search term.&lt;/p&gt;

&lt;p&gt;If you clicked the link in the previous paragraph, you'll have noticed that it's possible to filter someone else's list of starred repos. This can be useful for 'recommendations' and I used this recently when I was trying to find a React context-related package that I'd seen starred on the dashboard — it wasn't in my list of starred repos. I was pretty sure that &lt;a href="https://github.com/pelotom"&gt;Tom Crockett&lt;/a&gt; had starred it, so I filtered his list using &lt;a href="https://github.com/pelotom?tab=stars&amp;amp;utf8=%E2%9C%93&amp;amp;q=&amp;amp;q=context"&gt;'context'&lt;/a&gt; as the search term and found what I was looking for: &lt;a href="https://github.com/dai-shi/react-tracked"&gt;&lt;code&gt;react-tracked&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;When combined with the features outlined above, I think GitHub stars are useful for discovering and choosing packages. I just don't pay much attention to the total star counts.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Title photo by Daniel Olah on Unsplash.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>github</category>
    </item>
    <item>
      <title>RxJS: Typing zipWith</title>
      <dc:creator>Nicholas Jamieson</dc:creator>
      <pubDate>Mon, 17 Feb 2020 09:05:56 +0000</pubDate>
      <link>https://dev.to/cartant/rxjs-typing-zipwith-15km</link>
      <guid>https://dev.to/cartant/rxjs-typing-zipwith-15km</guid>
      <description>&lt;p&gt;&lt;em&gt;This article was originally published on &lt;a href="https://ncjamieson.com/typing-zipwith/"&gt;my blog&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;




&lt;p&gt;Much of what we are doing with RxJS, for version 7, is focused on improving the package's types.&lt;/p&gt;

&lt;p&gt;RxJS version 6 was released in April 2018 and, at that time, the current version of TypeScript was 2.8. With the bump to version 7, we can update this minimum-supported version of TypeScript and can take advantage of some of TypeScript's more recently-added features to simplify the package's types whilst making them more accurate and more flexible.&lt;/p&gt;

&lt;p&gt;This article, we'll look at the types that have been declared for a new operator: &lt;code&gt;zipWith&lt;/code&gt;. In particular, we'll look at how they work and at the TypeScript features upon which they rely.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's zipWith?
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;zipWith&lt;/code&gt; isn't really a new operator; it's the deprecated &lt;code&gt;zip&lt;/code&gt; operator renamed.&lt;/p&gt;

&lt;p&gt;When RxJS version 6 was released, there were a handful of operators that had the same name as observable creators: &lt;code&gt;concat&lt;/code&gt;; &lt;code&gt;combineLatest&lt;/code&gt;; &lt;code&gt;merge&lt;/code&gt;; &lt;code&gt;race&lt;/code&gt;; and &lt;code&gt;zip&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Prior to the introduction of &lt;code&gt;pipe&lt;/code&gt;, these operators having the same name wasn't a problem, as operators were attached to &lt;code&gt;Observable.prototype&lt;/code&gt;. However, when pipeable operators were introduced, the operators became static functions that had the same name as the creators:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;zip&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;rxjs&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// the creator&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;zip&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;rxjs/operators&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// the operator&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Operators are just functions that take an observable and return an observable, so the operators were deprecated and the recommendation was to use the creators instead, like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;answers&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;42&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;pipe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;source&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;zip&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;source&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;54&lt;/span&gt;&lt;span class="p"&gt;)));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Anyway, the above-mentioned operators are being renamed: a &lt;code&gt;With&lt;/code&gt; suffix is being added — yielding operator names similar to those in &lt;a href="http://reactivex.io/RxJava/3.x/javadoc/io/reactivex/rxjava3/core/Observable.html#zipWith-io.reactivex.rxjava3.core.ObservableSource-io.reactivex.rxjava3.functions.BiFunction-"&gt;RxJava&lt;/a&gt; — and they can be used like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;answers&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;42&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;pipe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;zipWith&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;of&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;54&lt;/span&gt;&lt;span class="p"&gt;)));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;&lt;code&gt;zipWith&lt;/code&gt; isn't really new and it's not especially interesting, but the types in its declaration are representative of the changes that are happening in RxJS version 7, so let's take a look at those.&lt;/p&gt;

&lt;h2&gt;
  
  
  Some background on RxJS's types
&lt;/h2&gt;

&lt;p&gt;Let's look at two areas in which the package's types were problematic:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;union return types; and&lt;/li&gt;
&lt;li&gt;functions that take an arbitrary number of arguments.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let's look at union return types first.&lt;/p&gt;

&lt;h2&gt;
  
  
  Union return types
&lt;/h2&gt;

&lt;p&gt;We'll use this as our example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;random&lt;/span&gt;&lt;span class="p"&gt;()).&lt;/span&gt;&lt;span class="nx"&gt;pipe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nx"&gt;concatMap&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;
    &lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mf"&gt;0.05&lt;/span&gt;
      &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Yikes, rolled a 1!&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mf"&gt;0.95&lt;/span&gt;
      &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;floor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Yay, rolled a 20!&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;It might look a little contrived, but situations often arise in NgRx and &lt;code&gt;redux-observable&lt;/code&gt; in which observable streams of different actions — i.e. different types — are returned from a projection function.&lt;/p&gt;

&lt;p&gt;In RxJS version 6.3, the snippet would not have compiled and the following error would have been effected:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Type 'Observable&amp;lt;number&amp;gt; | Observable&amp;lt;string&amp;gt;' is not
assignable to type 'ObservableInput&amp;lt;number&amp;gt;'.
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;The problem is that the projection function passed to &lt;code&gt;concatMap&lt;/code&gt; returns either an &lt;code&gt;Observable&amp;lt;number&amp;gt;&lt;/code&gt; or an &lt;code&gt;Observable&amp;lt;string&amp;gt;&lt;/code&gt; — depending upon the roll — and it's not possible (or safe) for TypeScript to determine that &lt;code&gt;Observable&amp;lt;number | string&amp;gt;&lt;/code&gt; is what should be inferred. Well, not without some help.&lt;/p&gt;

&lt;p&gt;In January 2019, Google's &lt;a href="https://github.com/alxhub"&gt;Alex Rickabaugh&lt;/a&gt; — he's on the Angular team — came up with a solution: the &lt;code&gt;ObservedValueOf&lt;/code&gt; type. And it looks like this:&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;ObservedValueOf&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;O&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;O&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nx"&gt;ObservableInput&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;infer&lt;/span&gt; &lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="nx"&gt;T&lt;/span&gt;
  &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;never&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;It extracts the value type from an &lt;code&gt;ObservableInput&lt;/code&gt;. And it can be used like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;concatMap&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;O&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nx"&gt;ObservableInput&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nx"&gt;project&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;index&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;O&lt;/span&gt;
&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nx"&gt;OperatorFunction&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;ObservedValueOf&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;O&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Using &lt;code&gt;ObservedValueOf&lt;/code&gt; in the &lt;code&gt;concatMap&lt;/code&gt; signature solves the problem and in our snippet, &lt;code&gt;result&lt;/code&gt; is inferred to be &lt;code&gt;Observable&amp;lt;number | string&amp;gt;&lt;/code&gt;. How it manages to solve the problem isn't immediately obvious, so let's take a closer look.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;O extends ObservableInput&amp;lt;any&amp;gt;&lt;/code&gt; type parameter imposes a constraint that the projection function's return value must be an &lt;code&gt;ObservableInput&lt;/code&gt;. &lt;code&gt;Observable&amp;lt;number&amp;gt;&lt;/code&gt; satisfies this constraint, as an &lt;code&gt;Observable&lt;/code&gt; is a valid &lt;code&gt;ObservableInput&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Observable&amp;lt;number&amp;gt; | Observable&amp;lt;string&amp;gt;&lt;/code&gt; also satisfies the constraint as both types within the union are &lt;code&gt;ObservableInput&lt;/code&gt;s. That means that &lt;code&gt;O&lt;/code&gt; is inferred to be &lt;code&gt;Observable&amp;lt;number&amp;gt; | Observable&amp;lt;string&amp;gt;&lt;/code&gt; and that's what's passed to &lt;code&gt;ObservedValueOf&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;TypeScript's conditional types have an interesting property: they are &lt;a href="https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-8.html#distributive-conditional-types"&gt;distributive&lt;/a&gt;. That is, the "conditional types are automatically distributed over union types during instantiation."&lt;/p&gt;

&lt;p&gt;That means that:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nx"&gt;ObservedValueOf&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Observable&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nx"&gt;Observable&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;is effectively resolved as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nx"&gt;ObservedValueOf&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Observable&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nx"&gt;ObservedValueOf&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Observable&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;which is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kr"&gt;number&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;And that's how &lt;code&gt;ObservedValueOf&lt;/code&gt; solves the problem of projection functions returning union types.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;ObservedValueOf&lt;/code&gt; was introduced in RxJS 6.4.0 and, unfortunately, it broke a whole bunch of Angular projects. The minimum-supported TypeScript version for RxJS version 6 was always considered to be 2.8 — as that was the latest TypeScript version when RxJS version 6 was released. However, Angular 6.1.0 &lt;a href="https://github.com/angular/angular-cli/blob/52edee5c28c5013600f2f795c5f7b15b5c09935d/packages/schematics/angular/utility/latest-versions.ts#L12-L14"&gt;depended upon RxJS &lt;code&gt;^6.0.0&lt;/code&gt; and TypeScript &lt;code&gt;~2.7.2&lt;/code&gt;&lt;/a&gt; and that version of TypeScript did not support conditional types — which were introduced in version 2.8.&lt;/p&gt;

&lt;p&gt;Because of this breakage, there have not been many subsequent changes to the types in RxJS version 6. Improvements to the package's types are constrained by the minimum-supported TypeScript version of 2.8 and by not being able to make changes to type parameters.&lt;/p&gt;

&lt;p&gt;In RxJS version 7, the minimum-supported version of TypeScript will be bumped and numerous type parameters will be repurposed. We'll look at these repurposed type parameters next, when we see how another problem was solved: passing arbitrary numbers of arguments to functions.&lt;/p&gt;

&lt;h2&gt;
  
  
  Arbitrary numbers of arguments
&lt;/h2&gt;

&lt;p&gt;In September 2019, &lt;a href="https://twitter.com/BenLesh"&gt;Ben Lesh&lt;/a&gt; added a type to support the passing of an arbitrary number of arguments to functions like &lt;code&gt;concat&lt;/code&gt;. Like &lt;code&gt;ObservedValueOf&lt;/code&gt; it's a conditional type and it looks like this:&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;ObservedValuesFromArray&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;A&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;A&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nb"&gt;Array&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;ObservableInput&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;infer&lt;/span&gt; &lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="nx"&gt;T&lt;/span&gt;
  &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;never&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Prior to the introduction of &lt;code&gt;ObservedValuesFromArray&lt;/code&gt;, functions like &lt;code&gt;concat&lt;/code&gt; had to have &lt;a href="https://github.com/ReactiveX/rxjs/blob/b8cb3a98d87d1db278b700ec35669f31e42bc258/src/internal/observable/concat.ts#L20-L31"&gt;numerous overload signatures&lt;/a&gt; — a signature for one argument, another for two arguments, etc. There were a limited number of these signatures — typically six — and if the number of arguments passed exceeded the limit, the type information was lost.&lt;/p&gt;

&lt;p&gt;With &lt;code&gt;ObservedValuesFromArray&lt;/code&gt;, only a single signature is needed and it's type-safe regardless of the number of arguments that are passed. Used with &lt;code&gt;concat&lt;/code&gt; looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;concat&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;A&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nx"&gt;ObservableInput&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;observables&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;A&lt;/span&gt;
&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nx"&gt;Observable&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;ObservedValuesFromArray&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;A&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;It uses TypeScript's support for &lt;a href="https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-0.html#rest-elements-in-tuple-types"&gt;rest elements in tuple types&lt;/a&gt; and when called like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;answers&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;concat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;of&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;42&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;fifty-four&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;&lt;code&gt;A&lt;/code&gt; will be inferred to be &lt;code&gt;[Observable&amp;lt;number&amp;gt;, Observable&amp;lt;string&amp;gt;]&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;[Observable&amp;lt;number&amp;gt;, Observable&amp;lt;string&amp;gt;]&lt;/code&gt; tuple extends the array type &lt;code&gt;Array&amp;lt;number | string&amp;gt;&lt;/code&gt;, so &lt;code&gt;ObservedValuesFromArray&lt;/code&gt; will infer &lt;code&gt;T&lt;/code&gt; to be &lt;code&gt;number | string&lt;/code&gt;. And that means that &lt;code&gt;answers&lt;/code&gt; will be inferred to be &lt;code&gt;Observable&amp;lt;number | string&amp;gt;&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;This is a huge improvement for the package's types. The elimination of overload signatures and the correct type inference — regardless of the number of passed arguments — are significant wins. However, the change is a breaking one, as the type parameter is repurposed. Let's take a closer look at the repurposing.&lt;/p&gt;

&lt;p&gt;Prior to the removal of the overload signatures, the single-argument signature looked like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;concat&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;o&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ObservableInput&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nx"&gt;Observable&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;So code like this would have been valid (weird and definitely not recommended, but valid nonetheless):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;concat&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;([]);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;With the removal of the overload signatures, this will break — as the type parameter refers to the arguments' tuple type and not the observable's element type.&lt;/p&gt;

&lt;h2&gt;
  
  
  Typing zip
&lt;/h2&gt;

&lt;p&gt;The types for &lt;code&gt;zip&lt;/code&gt; are similar to those used for &lt;code&gt;concat&lt;/code&gt; but there is a difference: &lt;code&gt;zip&lt;/code&gt; emits an array containing values received from its source observables. So the inference of an union type from a tuple type is not what's needed. What's needed is a &lt;a href="https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-1.html#mapped-types-on-tuples-and-arrays"&gt;mapped-tuple type&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Taking this into account, &lt;code&gt;ObservedValuesFromArray&lt;/code&gt; has been renamed to &lt;code&gt;ObservedValueUnionFromArray&lt;/code&gt;:&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;ObservedValueUnionFromArray&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;A&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
  &lt;span class="nx"&gt;A&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nb"&gt;Array&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;ObservableInput&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;infer&lt;/span&gt; &lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="nx"&gt;T&lt;/span&gt;
    &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;never&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;And another type — that infers a tuple — has been added:&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;ObservedValueTupleFromArray&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;A&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
  &lt;span class="nx"&gt;A&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nb"&gt;Array&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;ObservableInput&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;K&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="kr"&gt;keyof&lt;/span&gt; &lt;span class="nx"&gt;A&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="nx"&gt;ObservedValueOf&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;A&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;K&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;never&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;This looks complicated, but what it does is reasonably straightforward: if &lt;code&gt;A&lt;/code&gt; is a tuple of &lt;code&gt;ObservableInput&lt;/code&gt;s, it maps &lt;code&gt;A&lt;/code&gt; to a tuple in which each element has the type of the &lt;code&gt;ObservableInput&lt;/code&gt;'s value — using Alex's type.&lt;/p&gt;

&lt;p&gt;Let's look at an example:&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;Example&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;ObservedValueTupleFromArray&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;
  &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;Observable&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Observable&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Here, &lt;code&gt;Example&lt;/code&gt; will be inferred to be &lt;code&gt;[number, string]&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;With the mapped-tuple type, &lt;code&gt;zip&lt;/code&gt; is similar to &lt;code&gt;concat&lt;/code&gt; and no longer requires overload signatures and correctly infers the types for an arbitrary number of arguments:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;zip&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;A&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nx"&gt;ObservableInput&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;observables&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;A&lt;/span&gt;
&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nx"&gt;Observable&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;ObservedValueTupleFromArray&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;A&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h2&gt;
  
  
  Typing zipWith
&lt;/h2&gt;

&lt;p&gt;The typing for &lt;code&gt;zipWith&lt;/code&gt; is similar to that for &lt;code&gt;zip&lt;/code&gt;, but there is a small difference: not all of the elements in the zipped array are present in the arguments' tuple. The initial element in the zipped array will be the value received from the source observable to which the &lt;code&gt;zipWith&lt;/code&gt; operator is applied.&lt;/p&gt;

&lt;p&gt;That is, when it's used like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;answers&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;42&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;pipe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;zipWith&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;of&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;fifty-four&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;the type of &lt;code&gt;answers&lt;/code&gt; needs to be inferred as &lt;code&gt;[number, string]&lt;/code&gt;, but &lt;code&gt;[string]&lt;/code&gt; is what's inferred when &lt;code&gt;ObservedValueTupleFromArray&lt;/code&gt; is applied to the arguments tuple.&lt;/p&gt;

&lt;p&gt;To get the type that we need, &lt;code&gt;number&lt;/code&gt; has to be be added to the head of the tuple.&lt;/p&gt;

&lt;p&gt;We can do that using another type:&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;Cons&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;A&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
  &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;arg&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;rest&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;A&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="p"&gt;((...&lt;/span&gt;&lt;span class="nx"&gt;args&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;infer&lt;/span&gt; &lt;span class="nx"&gt;U&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="nx"&gt;U&lt;/span&gt;
    &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;never&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;This type is a little tricky. It's a conditional type that uses a relationship between two intermediate function types to infer a tuple type that adds &lt;code&gt;T&lt;/code&gt; at the head of &lt;code&gt;A&lt;/code&gt;. It works by forming an intermediate function that takes an argument of type &lt;code&gt;T&lt;/code&gt; followed by arguments for each of the types in &lt;code&gt;A&lt;/code&gt;. &lt;code&gt;U&lt;/code&gt; is then inferred from the arguments of the intermediate function, effectively adding &lt;code&gt;T&lt;/code&gt; to the head of &lt;code&gt;A&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;We can use &lt;code&gt;Cons&lt;/code&gt; to add &lt;code&gt;T&lt;/code&gt; at the tuple's head, like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;zipWith&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;A&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nx"&gt;ObservableInput&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;observables&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;A&lt;/span&gt;
&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nx"&gt;OperatorFunction&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Cons&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;ObservedValueTupleFromArray&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;A&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;And with the &lt;code&gt;zipWith&lt;/code&gt; signature declared like this, &lt;code&gt;answers&lt;/code&gt; — in the above snippet — is inferred to be &lt;code&gt;Observable&amp;lt;[number, string]&amp;gt;&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's still to do?
&lt;/h2&gt;

&lt;p&gt;For version 7, the core team will be taking the types that we've looked here and will be applying them to other functions in the package. The goal is to get as much of the API as possible supporting the inference of correct types when an arbitrary number of arguments are passed. And to get rid of all those overload signatures.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Title photo by Ricardo Gomez Angel on Unsplash.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>rxjs</category>
      <category>typescript</category>
    </item>
    <item>
      <title>Be Careful with Array Mutators</title>
      <dc:creator>Nicholas Jamieson</dc:creator>
      <pubDate>Fri, 27 Dec 2019 08:51:37 +0000</pubDate>
      <link>https://dev.to/cartant/be-careful-with-array-mutators-5pe</link>
      <guid>https://dev.to/cartant/be-careful-with-array-mutators-5pe</guid>
      <description>&lt;p&gt;&lt;em&gt;This article was originally published on &lt;a href="https://ncjamieson.com/be-careful-with-array-mutators/"&gt;my blog&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;




&lt;p&gt;A while ago, I wrote a linting rule to highlight an error that I’d made on a few occasions. Let’s look at the error — and its variations — and then at the rule that prevents it.&lt;/p&gt;

&lt;h2&gt;
  
  
  The error
&lt;/h2&gt;

&lt;p&gt;If you are used to working with &lt;a href="https://www.martinfowler.com/bliki/FluentInterface.html"&gt;fluent APIs&lt;/a&gt; — perhaps with &lt;a href="https://github.com/d3/d3"&gt;D3&lt;/a&gt; or &lt;a href="https://github.com/lodash/lodash"&gt;lodash&lt;/a&gt; — it feels natural to write &lt;code&gt;Array&lt;/code&gt;-based code like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;developers&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;employees&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;role&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;developer&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;sort&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Which is fine. There’s no error in that code.&lt;/p&gt;

&lt;p&gt;However, in situations in which you don’t need to filter or map, you might write something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;sorted&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;names&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;sort&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;It feels natural, but there’s a potential error in there. And it’s an error that can effect hard-to-find bugs. It’s also an error that’s easy to overlook in code reviews.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;sort&lt;/code&gt; method mutates the array. It sorts the array in place and returns a reference to the array itself. It does not return a sorted copy of the array. So the &lt;code&gt;sorted&lt;/code&gt; and &lt;code&gt;names&lt;/code&gt; variables both reference the same, sorted array. And it means that — unless the array was already sorted — any code using the &lt;code&gt;names&lt;/code&gt; variable will be dealing with an array in which the elements that been rearranged.&lt;/p&gt;

&lt;p&gt;So why is the code in the first snippet okay? It’s because &lt;code&gt;sort&lt;/code&gt; is applied to the array returned by &lt;code&gt;map&lt;/code&gt; — a transient array to which there are no references.&lt;/p&gt;

&lt;h2&gt;
  
  
  The rule
&lt;/h2&gt;

&lt;p&gt;The fundamental problem is the use of the return value when the &lt;code&gt;sort&lt;/code&gt; method is applied to an array that is referenced elsewhere in the program.&lt;/p&gt;

&lt;p&gt;If the return value is not used, it’s fine — as the intent is clear:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nx"&gt;names&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;sort&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;And it’s also fine if the &lt;code&gt;sort&lt;/code&gt; method is applied to an array that has no referencing variable:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;names&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;bob&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;alice&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;sort&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;It is a potential problem if the result is assigned to another variable:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;sorted&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;names&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;sort&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Or assigned to a property:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;names&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;names&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;sort&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Or passed as an argument:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;names&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;sort&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;The rule I wrote is named &lt;code&gt;no-assign-mutated-array&lt;/code&gt; and is in the &lt;code&gt;tslint-etc&lt;/code&gt; package. The source code is &lt;a href="https://github.com/cartant/tslint-etc/blob/master/source/rules/noAssignMutatedArrayRule.ts"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;It works by searching for method calls — like &lt;code&gt;sort&lt;/code&gt; — that mutate arrays and checking to see if they are statements. The search is done using &lt;a href="https://twitter.com/phenomnominal"&gt;Craig Spence&lt;/a&gt;’s awesome &lt;a href="https://github.com/phenomnomnominal/tsquery"&gt;&lt;code&gt;tsquery&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;If the call is a statement, the return value isn’t used — so there is no potential problem.&lt;/p&gt;

&lt;p&gt;If the call is not a statement, the rule determines whether or not the array upon which the call is made is transient and effects a rule failure if it isn’t.&lt;/p&gt;

&lt;p&gt;There are several methods on &lt;code&gt;Array.prototype&lt;/code&gt; that mutate the array and return a reference to the mutated array — &lt;code&gt;fill&lt;/code&gt;, &lt;code&gt;reverse&lt;/code&gt;, &lt;code&gt;sort&lt;/code&gt;, and &lt;code&gt;splice&lt;/code&gt; — and the rule is enforced for all of them.&lt;/p&gt;

&lt;h2&gt;
  
  
  The future
&lt;/h2&gt;

&lt;p&gt;In the &lt;a href="https://github.com/Microsoft/TypeScript/issues/29288"&gt;TypeScript roadmap &lt;/a&gt;— for January to June 2019 — it was announced that TypeScript will be switching to ESLint — using &lt;a href="https://github.com/typescript-eslint/typescript-eslint"&gt;&lt;code&gt;@typescript-eslint/parser&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;So sometime soon, I’ll start converting the rules in &lt;code&gt;tslint-etc&lt;/code&gt; and &lt;code&gt;rxjs-tslint-rules&lt;/code&gt; from TSLint rules to ESLint rules. Doing that should be … interesting. And I imagine it’ll prompt me to write a few more linting articles.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Title photo by Corinne Kutz on Unsplash.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>typescript</category>
      <category>javascript</category>
      <category>webdev</category>
    </item>
    <item>
      <title>TIL: Destructuring Property Assignment</title>
      <dc:creator>Nicholas Jamieson</dc:creator>
      <pubDate>Sun, 22 Dec 2019 07:37:17 +0000</pubDate>
      <link>https://dev.to/cartant/til-destructuring-property-assignment-5j2</link>
      <guid>https://dev.to/cartant/til-destructuring-property-assignment-5j2</guid>
      <description>&lt;p&gt;&lt;em&gt;This article was originally published on &lt;a href="https://ncjamieson.com/til-destructuring-property-assignment/"&gt;my blog&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;




&lt;p&gt;Until recently, I wasn't aware of the JavaScript syntax for destructuring property assignment.&lt;/p&gt;

&lt;p&gt;I knew that I could destructure array elements and object properties in variable declarations, like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;vowel&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;a&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;e&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;i&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;o&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;u&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;vowel&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// a&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Alice&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Alice&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;And I knew that I could destructure an array and assign an element to a previously declared variable, like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;vowel&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;vowel&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;a&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;e&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;i&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;o&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;u&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;vowel&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// a&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;But I didn't know how to destructure an object and assign a property to a previously declared variable. I tried this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Alice&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;But this error was effected:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SyntaxError: Unexpected token '='
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;The problem was that the braces surrounding the &lt;code&gt;name&lt;/code&gt; variable were parsed as a block. To be parsed as &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment"&gt;destructuring property assignment&lt;/a&gt;, the assignment expression needs to be surrounded by parentheses, like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Alice&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Alice&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;It's worth noting that if you rely upon &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Lexical_grammar#Automatic_semicolon_insertion"&gt;automatic semicolon insertion&lt;/a&gt;, you may need to precede the parentheses with a semicolon to prevent the assignment expression from being used to execute a function on the previous line.&lt;/p&gt;

&lt;p&gt;For example, this usage:&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;assigning&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Alice&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Will effect this error:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;TypeError: console.log(...) is not a function
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;






&lt;p&gt;&lt;em&gt;Title photo by Florian Klauer on Unsplash.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>todayilearned</category>
      <category>webdev</category>
    </item>
    <item>
      <title>TIL: String.raw</title>
      <dc:creator>Nicholas Jamieson</dc:creator>
      <pubDate>Sat, 21 Dec 2019 03:14:37 +0000</pubDate>
      <link>https://dev.to/cartant/til-string-raw-9an</link>
      <guid>https://dev.to/cartant/til-string-raw-9an</guid>
      <description>&lt;p&gt;&lt;em&gt;This article was originally published on &lt;a href="https://ncjamieson.com/til-string-raw/"&gt;my blog&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;




&lt;p&gt;Something that's always annoyed me — because I always seem to mess it up — is having to escape the escape character (&lt;code&gt;\&lt;/code&gt;) in some JavaScript string literals.&lt;/p&gt;

&lt;p&gt;Well, it turns out there's a feature that means having to do this can be avoided entirely.&lt;/p&gt;

&lt;h2&gt;
  
  
  Other languages
&lt;/h2&gt;

&lt;p&gt;C# uses the &lt;code&gt;@&lt;/code&gt; character as a verbatim identifier and when it's applied to a string literal, it works like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="c1"&gt;// These strings are equivalent:&lt;/span&gt;
&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;verbatim&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;@"C:\Windows\system.ini"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;escaped&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"C:\\Windows\\system.ini"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;This is part of the C# language syntax.&lt;/p&gt;

&lt;h2&gt;
  
  
  JavaScript
&lt;/h2&gt;

&lt;p&gt;In JavaScript, the mechanism is a little different. It doesn't extend the syntax. Instead, it leverages template literals and their tags.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;String&lt;/code&gt; object has a static &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/raw"&gt;&lt;code&gt;raw&lt;/code&gt;&lt;/a&gt; method that is intended to be used as a &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals#Tagged_templates"&gt;template-literal tag&lt;/a&gt;, like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// These strings are equivalent:&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;raw&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;raw&lt;/span&gt;&lt;span class="s2"&gt;`C:\Windows\system.ini`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;escaped&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;C:&lt;/span&gt;&lt;span class="se"&gt;\\&lt;/span&gt;&lt;span class="s2"&gt;Windows&lt;/span&gt;&lt;span class="se"&gt;\\&lt;/span&gt;&lt;span class="s2"&gt;system.ini&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Having to put backslash-delimited Windows paths in JavaScript literals isn't something that I've ever had to do.&lt;/p&gt;

&lt;p&gt;However, I often have to escape escape characters when I'm dynamically creating a regular expression using the &lt;code&gt;RegExp&lt;/code&gt; constructor. And in these situations, not having to escape the escape characters makes things much clearer:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;regExp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nb"&gt;RegExp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;raw&lt;/span&gt;&lt;span class="s2"&gt;`(\b|_)&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;word&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;(\b|_)`&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h2&gt;
  
  
  ES2018
&lt;/h2&gt;

&lt;p&gt;It's worth noting that there are differences in how these 'raw' template literals are handled in &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals#Tagged_templates_and_escape_sequences"&gt;different JavaScript runtimes&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;In ES2016, this template literal will effect an error, because &lt;code&gt;\u&lt;/code&gt; is interpreted as a Unicode escape sequence:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;directory&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;raw&lt;/span&gt;&lt;span class="s2"&gt;`C:\images\unsplash`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;In ES2018, this behaviour was changed and — as long as a tag function is applied — no error will be effected.&lt;/p&gt;

&lt;h2&gt;
  
  
  More template-literal tags
&lt;/h2&gt;

&lt;p&gt;If template-literal tags are something you've not encountered before, you might also want to check out the &lt;a href="https://github.com/declandewet/common-tags"&gt;&lt;code&gt;common-tags&lt;/code&gt;&lt;/a&gt; package. It has a whole bunch of extremely useful tag functions.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Title photo by Icons8 Team on Unsplash.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>todayilearned</category>
      <category>webdev</category>
    </item>
    <item>
      <title>TypeScript: Don't Export const enums</title>
      <dc:creator>Nicholas Jamieson</dc:creator>
      <pubDate>Sat, 14 Dec 2019 02:34:27 +0000</pubDate>
      <link>https://dev.to/cartant/typescript-don-t-export-const-enums-6ip</link>
      <guid>https://dev.to/cartant/typescript-don-t-export-const-enums-6ip</guid>
      <description>&lt;p&gt;&lt;em&gt;This article was originally published on &lt;a href="https://ncjamieson.com/dont-export-const-enums/"&gt;my blog&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;




&lt;p&gt;If you are writing a library and you export a &lt;code&gt;const enum&lt;/code&gt;, some developers will not be able to compile their applications if they import your library. Let's look at why.&lt;/p&gt;

&lt;h2&gt;
  
  
  Non-const enums
&lt;/h2&gt;

&lt;p&gt;When you declare an &lt;code&gt;enum&lt;/code&gt;, TypeScript will generate code for it. For example, this TypeScript snippet:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kr"&gt;enum&lt;/span&gt; &lt;span class="nx"&gt;Bool&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;FileNotFound&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Bool&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;FileNotFound&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;will compile to this JavaScript:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;Bool&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;Bool&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;Bool&lt;/span&gt;&lt;span class="p"&gt;[(&lt;/span&gt;&lt;span class="nx"&gt;Bool&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;True&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;True&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nx"&gt;Bool&lt;/span&gt;&lt;span class="p"&gt;[(&lt;/span&gt;&lt;span class="nx"&gt;Bool&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;False&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;False&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nx"&gt;Bool&lt;/span&gt;&lt;span class="p"&gt;[(&lt;/span&gt;&lt;span class="nx"&gt;Bool&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;FileNotFound&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;FileNotFound&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;})(&lt;/span&gt;&lt;span class="nx"&gt;Bool&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;Bool&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{}));&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Bool&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;FileNotFound&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;The reasons for this are explained in the &lt;a href="//www.typescriptlang.org/docs/handbook/enums.html"&gt;documentation&lt;/a&gt;. However, some developers don't need the features provided by this style of declaration and don't want the costs involved — they just want to use enums instead of constants.&lt;/p&gt;

&lt;h2&gt;
  
  
  const enums
&lt;/h2&gt;

&lt;p&gt;When an &lt;code&gt;enum&lt;/code&gt; is declared as &lt;code&gt;const&lt;/code&gt;, TypeScript doesn't generate code for the declaration. For example, this TypeScript snippet:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="kr"&gt;enum&lt;/span&gt; &lt;span class="nx"&gt;Bool&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;FileNotFound&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Bool&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;FileNotFound&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;will compile to this JavaScript:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="cm"&gt;/* FileNotFound */&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;No code is generated for the &lt;code&gt;enum&lt;/code&gt; declaration. Which is great — it's just like using a constant — but there is a problem.&lt;/p&gt;

&lt;h2&gt;
  
  
  Isolated modules
&lt;/h2&gt;

&lt;p&gt;In the above snippets, TypeScript has access to the &lt;code&gt;const enum&lt;/code&gt; declaration, as it's in the same module as the declaration for the &lt;code&gt;value&lt;/code&gt; variable.&lt;/p&gt;

&lt;p&gt;However, if the &lt;code&gt;const enum&lt;/code&gt; declaration is in a different module — and is imported into the module that contains the variable declaration — TypeScript will have to read both modules to determine that &lt;code&gt;Bool.FileNotFound&lt;/code&gt; should be replaced with &lt;code&gt;2&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;This is a problem because some developers use a workflow that separates type checking from compilation — with compilation happening on an isolated-module basis:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the compiler reads a TypeScript module;&lt;/li&gt;
&lt;li&gt;the module's type information is stripped; and&lt;/li&gt;
&lt;li&gt;what's left is the JavaScript module that the compiler writes.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This compilation process does not read imported modules, so it's not possible for it to support the replacement of &lt;code&gt;const enum&lt;/code&gt; members — like &lt;code&gt;Bool.FileNotFound&lt;/code&gt; — with their values.&lt;/p&gt;

&lt;p&gt;The &lt;a href="https://github.com/Microsoft/TypeScript/wiki/Using-the-Compiler-API#a-simple-transform-function"&gt;&lt;code&gt;transpileModule&lt;/code&gt;&lt;/a&gt; function in the TypeScript compiler API performs this type of compilation, as does &lt;a href="https://babeljs.io/docs/en/babel-plugin-transform-typescript"&gt;&lt;code&gt;@babel/plugin-transform-typescript&lt;/code&gt;&lt;/a&gt; — which is what's used in &lt;a href="https://github.com/facebook/create-react-app"&gt;&lt;code&gt;create-react-app&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;TypeScript has an &lt;code&gt;isolatedModules&lt;/code&gt; compiler option that performs additional checks to ensure that the compiled code is safe for this type of compilation process. If you are are writing a library, you should enable this option to ensure that you are not exporting &lt;code&gt;const enum&lt;/code&gt; declarations and that all TypeScript developers can compile code that imports your library.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Title photo by Waldemar Brandt on Unsplash.&lt;/em&gt;&lt;/p&gt;

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