<?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>Forem: Ronni Egeriis Persson</title>
    <description>The latest articles on Forem by Ronni Egeriis Persson (@egeriis).</description>
    <link>https://forem.com/egeriis</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%2F3352%2F579824.jpeg</url>
      <title>Forem: Ronni Egeriis Persson</title>
      <link>https://forem.com/egeriis</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/egeriis"/>
    <language>en</language>
    <item>
      <title>On NPM Packages and Bundle Size Impact</title>
      <dc:creator>Ronni Egeriis Persson</dc:creator>
      <pubDate>Wed, 12 Jun 2019 20:35:36 +0000</pubDate>
      <link>https://forem.com/egeriis/on-npm-packages-and-bundle-size-impact-54f5</link>
      <guid>https://forem.com/egeriis/on-npm-packages-and-bundle-size-impact-54f5</guid>
      <description>&lt;p&gt;&lt;em&gt;Edit, June 13, 2019: What a timing... &lt;a href="https://www.pika.dev/cdn"&gt;pika.dev&lt;/a&gt; have just been released, which is a CDN for ES modules. Their search engine also reveals which packages does not have an ES module entry, try searching for &lt;code&gt;moment&lt;/code&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;We've got a bundle size problem, and the &lt;a href="https://www.reddit.com/r/ProgrammerHumor/comments/6s0wov/heaviest_objects_in_the_universe/"&gt;heaviest objects of the universe&lt;/a&gt; carry a lot of blame. Here's a quick write up on the matter that I hope can spur some debate.&lt;/p&gt;

&lt;p&gt;Emphasis on web app bundle size keeps increasing, which means that a lot of frontend engineers eyes are aimed at a search for things to exclude, tree shake, replace, lazy load, ... from their build output. But there's an elephant in the room, that no-one seems to be talking about: NPM packages and their distribution format.&lt;/p&gt;

&lt;p&gt;Some background on tree shaking and ES version in NPM before we dive in.&lt;/p&gt;

&lt;h1&gt;
  
  
  Tree Shaking
&lt;/h1&gt;

&lt;p&gt;Tree shaking is one of the key ingredients to keeping your application bundle size to a minimum. It's a mechanism used by bundlers like Webpack to remove unused pieces of code from dependencies. This is something that the bundlers can easily determine for ES modules (i.e. &lt;code&gt;import&lt;/code&gt;/&lt;code&gt;export&lt;/code&gt;, also known as Harmony modules), since there can be no side-effects.&lt;/p&gt;

&lt;p&gt;It is &lt;em&gt;not&lt;/em&gt; supported for CommonJS nor UMD modules. And this is the important piece of information you need.&lt;/p&gt;

&lt;h1&gt;
  
  
  ES2015+ in NPM Packages
&lt;/h1&gt;

&lt;p&gt;Most frontend engineers prefer to use modern ES features like ES modules, fat-arrow, spread operator, etc. The same is true for many library authors, especially those who are writing libs for web. This leads to the use of bundlers to produce the output which is published to NPM. And this is where we have a lot of potential for optimization.&lt;/p&gt;

&lt;p&gt;Casting a quick glance over some of the &lt;a href="https://www.npmjs.com/browse/depended"&gt;most depended upon packages&lt;/a&gt; in NPM reveals that a lot of them are publishing CommonJS modules only. In a big project I'm working on, we've got 1,773 NPM packages in node_modules, just 277 of these refer to an ES module build.&lt;/p&gt;

&lt;h1&gt;
  
  
  A Problem Shaping Up
&lt;/h1&gt;

&lt;p&gt;Let's outline the problem here:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;How many NPM dependencies does your app have? Likely a lot.&lt;/li&gt;
&lt;li&gt;Does your app use 100% of the code in those dependencies? Very unlikely.&lt;/li&gt;
&lt;li&gt;Can your bundler tree shake those unused code paths? Unlikely.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This problem is even recognized by the most depended upon package, &lt;code&gt;lodash&lt;/code&gt;, who's authors publish a specific ES module output as &lt;code&gt;lodash-es&lt;/code&gt;. This is great, as it allows us to use an optimized build of lodash, which can be tree shaken and wont include unused code in our app build.&lt;/p&gt;

&lt;p&gt;But this seems like an afterthought, better solutions are readily available and many popular libs does not offer a ES module build.&lt;/p&gt;

&lt;h1&gt;
  
  
  Problem Illustrated
&lt;/h1&gt;

&lt;p&gt;To illustrate the problem outlined above, I've initialized a simple reproduction &lt;a href="https://github.com/egeriis/bundler-experiment"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;code&gt;math&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;math&lt;/code&gt; is a small library with two exports, &lt;code&gt;cube&lt;/code&gt; and &lt;code&gt;square&lt;/code&gt;. I've set up rollup to produce both CJS and ES module output.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;code&gt;app&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;This contains a small app which is bundled using webpack. It consumes 1 function from &lt;code&gt;math&lt;/code&gt; and correctly tree shakes the unused export from it's output.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;code&gt;node&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;A small proof that the output of &lt;code&gt;math&lt;/code&gt; also works in Node.js-land with &lt;code&gt;require&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Outcome
&lt;/h2&gt;

&lt;p&gt;While this is a very small example, an impact on app bundle size is imminently visible when toggling between CJS and ES module output. &lt;/p&gt;

&lt;p&gt;Production build size with ES module is 1.1kb:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;            Asset     Size  Chunks             Chunk Names
  bundle.index.js  1.1 KiB       0  [emitted]  index
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;While it's 1.16kb with CJS and no tree shaking:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;            Asset      Size  Chunks             Chunk Names
  bundle.index.js  1.16 KiB       0  [emitted]  index
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Negligible difference for this teeny example, but the impact can be significant once you consider all the heavy objects in your &lt;code&gt;node_modules&lt;/code&gt; folder. &lt;/p&gt;

&lt;h1&gt;
  
  
  Problem Solved
&lt;/h1&gt;

&lt;p&gt;In our example above, we have managed to find a simple solution this problem. Our dependency &lt;code&gt;math&lt;/code&gt; can be used in both Node.js and bundler-land (and browser land, if you target modern browser), and it's simple to achieve.&lt;/p&gt;

&lt;h2&gt;
  
  
  How It Works
&lt;/h2&gt;

&lt;p&gt;If you bundle your app with a bundler that supports tree shaking (Webpack 2+, Rollup, and more), it will automatically resolve your dependencies' ES module if present. Your bundler will look for a &lt;code&gt;module&lt;/code&gt; entry in a depency's &lt;code&gt;package.json&lt;/code&gt; file before defaulting to &lt;code&gt;main&lt;/code&gt;. Take a look at &lt;code&gt;math&lt;/code&gt;'s &lt;code&gt;package.json&lt;/code&gt; for an example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  "name": "math",
  "version": "1.0.0",
  "main": "index.js",
  "module": "indexEs.js",
  "devDependencies": { ... }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Pretty simple. &lt;code&gt;math&lt;/code&gt; has two output destinations, one is a CJS module (&lt;code&gt;index.js&lt;/code&gt;), another a ES module (&lt;code&gt;indexEs.js&lt;/code&gt;).&lt;/p&gt;

&lt;h2&gt;
  
  
  One Gotcha
&lt;/h2&gt;

&lt;p&gt;I've had a library published for a while, which used this approach, and many users have been confused because it's been best practice to ignore &lt;code&gt;node_modules&lt;/code&gt; in Webpack for a long time. To utilize tree shaking, Webpack must be able to read dependencies' ES modules, so if you require backwards compatible app build, you should also transpile these dependencies in your app build step. This is good if you prioritize bundle size over build time.&lt;/p&gt;

&lt;h1&gt;
  
  
  Call for Action
&lt;/h1&gt;

&lt;p&gt;Library authors, please consider adding a &lt;code&gt;module&lt;/code&gt; entry to your &lt;code&gt;package.json&lt;/code&gt; and start producing an ES module version.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>npm</category>
      <category>webpack</category>
      <category>performance</category>
    </item>
    <item>
      <title>Generic typing of Redux modules in Flow</title>
      <dc:creator>Ronni Egeriis Persson</dc:creator>
      <pubDate>Mon, 09 Apr 2018 17:18:01 +0000</pubDate>
      <link>https://forem.com/egeriis/generic-typing-of-redux-modules-in-flow-384m</link>
      <guid>https://forem.com/egeriis/generic-typing-of-redux-modules-in-flow-384m</guid>
      <description>&lt;p&gt;While the official Flow docs present a solution to typing Redux modules, the way their example is designed implies copy/pasting the type definitions into each of the Redux modules.  This is not optimal.&lt;/p&gt;

&lt;p&gt;Let's examine &lt;a href="https://flow.org/en/docs/react/redux/#toc-typing-redux-thunk-actions"&gt;their example&lt;/a&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;Action&lt;/span&gt; &lt;span class="o"&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;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;FOO&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;foo&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;number&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;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;BAR&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;bar&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;boolean&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="nx"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;ThunkAction&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;dispatch&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Dispatch&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;getState&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;GetState&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;any&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nx"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;PromiseAction&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Action&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;type&lt;/span&gt; &lt;span class="nx"&gt;GetState&lt;/span&gt; &lt;span class="o"&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="nx"&gt;State&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nx"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;Dispatch&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;action&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Action&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nx"&gt;ThunkAction&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nx"&gt;PromiseAction&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;any&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Looking at the first three lines in above snippet, we see that their example has a static set of action types specified. This exposes an issue in applications where the state is spread into multiple modules, leading to duplicate code or other code smell.&lt;/p&gt;

&lt;p&gt;Using the method from above snippet in such application, we have to either:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Specify the types top-level and provide them access to &lt;em&gt;all&lt;/em&gt; action types of our application&lt;/li&gt;
&lt;li&gt;Copy/paste these type definitions for each Redux module—or, rather, the level at which you split your action types&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Both of these solutions lead to code smells.&lt;/p&gt;

&lt;h1&gt;
  
  
  Making Types Generic Using Generics
&lt;/h1&gt;

&lt;p&gt;So how do we create these types in a generic way? Using &lt;a href="https://flow.org/en/docs/types/generics/"&gt;generics&lt;/a&gt;!&lt;/p&gt;

&lt;p&gt;Remember, the main problem in the original code is that the type &lt;code&gt;Action&lt;/code&gt; is static. Essentially, all we need to do is to make that value variable.&lt;/p&gt;

&lt;p&gt;Here's my solution:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="nx"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;ThunkAction&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;S&lt;/span&gt;&lt;span class="p"&gt;,&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="p"&gt;(&lt;/span&gt;
  &lt;span class="nx"&gt;dispatch&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Dispatch&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;S&lt;/span&gt;&lt;span class="p"&gt;,&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="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;getState&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;GetState&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;S&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="nx"&gt;any&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="nx"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;PromiseAction&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="nb"&gt;Promise&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="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="nx"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;GetState&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;S&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="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;S&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="nx"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;Dispatch&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;S&lt;/span&gt;&lt;span class="p"&gt;,&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="p"&gt;(&lt;/span&gt;
  &lt;span class="nx"&gt;action&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;A&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nx"&gt;ThunkAction&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;S&lt;/span&gt;&lt;span class="p"&gt;,&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;PromiseAction&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="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;any&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Whoah, that's a lot of generics!&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Yeah, I know. But it's really not that complex:&lt;/p&gt;

&lt;p&gt;For the purpose of following Flow's own practices and for brevity, generics are named by one letter. &lt;code&gt;A&lt;/code&gt; stands for "Action" and &lt;code&gt;S&lt;/code&gt; for "State". These are the two types that we have to make variable, because they're different for each Redux module.&lt;/p&gt;

&lt;p&gt;Using generics we can require "arguments" to be passed where the types are used. Referring my solution, &lt;code&gt;ThunkAction&lt;/code&gt; requires two "arguments" to be passed, State and Action, so defining a thunk action could look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;FetchFooActions&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;ActionFoo&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nx"&gt;ActionBar&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;fetchFoo&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="nx"&gt;ThunkAction&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;State&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;FetchFooActions&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;dispatch&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;getState&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="cm"&gt;/* inside my mind I have a digital mind */&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;&lt;code&gt;State&lt;/code&gt; is the type definition for the state of our Redux module, and &lt;code&gt;FetchFooActions&lt;/code&gt; is a clear specification of the actions that are expected to be dispatched from calling &lt;code&gt;fetchFoo&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;If you need to use &lt;code&gt;PromiseAction&lt;/code&gt;, &lt;code&gt;GetState&lt;/code&gt; or &lt;code&gt;Dispatch&lt;/code&gt;, simply supply those with their generics "arguments":&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Supply your State and Action types to Dispatch, State only to GetState&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;cb&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;dispatch&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Dispatch&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;State&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Action&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;getState&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;GetState&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;State&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="p"&gt;};&lt;/span&gt;
&lt;span class="c1"&gt;// Supply Action type to PromiseAction&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;asyncAction&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="nx"&gt;PromiseAction&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Action&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="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We have now untangled the four types, &lt;code&gt;ThunkAction&lt;/code&gt;, &lt;code&gt;PromiseAction&lt;/code&gt;, &lt;code&gt;GetState&lt;/code&gt; and &lt;code&gt;Dispatch&lt;/code&gt;, so they can be shared across the application without code smell. But we even enabled ourselves to be more specific in our typing simultaneously. You can see this by attempting to dispatch an unexpected action in my full example:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://flow.org/try/#0MYewdgzgLgBAZgUysAFjAvDAFAOjwQwCcBzCASgwD4YAFQkAWwEsIEdCEIQAbANwSwBtAORQmUbgmEBdMgG4AUAoD0ymAHEEYBISbAFCAB4AHEIVhQAnsYQwAKigCuYANYBBYGPAAeAMoAaGDdqTCwFGBgAExZjfGQUAC4YABEYuNQ-QOD-cJhiJF8oOIQkzShC4r9KBQp0anwwS0UjU3MYKxtaemZWDy8wb2CMLsYWBEHKRQMTMwtrWzKKqHHfEOxa6l9mmbaO21SIWPjMoLWwiPxPJnAktxgAH3snVz7rgYDTh5GehFefYJqVBgDSaSlUMAASghIo5gDoFHtaCBoBBhm5CIR8JZvNBdGBiJMEfMYEtbJgAN65RysQgASUiSTAjgYACMdDkIqYUUkaMioBAFABfKbgv5gdrzAWIgCqxkixV5KLFw0pET2SWEjjlxQAtFz+cIOTB9RAeXyBcKlIjFfzZfLlgAxfBMSSRZUU3LqmCa7XLPXmnVwZ2u4RCkVqMWomBEzoOpCoG0QSPDO0K83Kx6J1OO4PQsWKODOK7geDxlCJrBkJIOZzuYvvIrLQJx+KJyPUVUwDhQRyEcVYaKHdIoQL5cqNhAbGCdiKgSCwE3DRDxLDCZQm5TCGAAajyBQnlZw1J09LIOCgKC0WEXdWnuQiEUHR1QWHJ0YfH4lNg1WvtCH9KKGven4msBESCvIwGCoElZAjOD5PsOr5fiU3q-rqJqBrmkRbhBigfnhuSWoKQA"&gt;Full example on flow.org/try&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I hope this is valuable inspiration. Feel free to comment or ask questions :)&lt;/p&gt;

</description>
      <category>redux</category>
      <category>flow</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Hi, I'm Ronni Egeriis Persson</title>
      <dc:creator>Ronni Egeriis Persson</dc:creator>
      <pubDate>Sun, 19 Feb 2017 20:18:35 +0000</pubDate>
      <link>https://forem.com/egeriis/hi-im-ronni-egeriis-persson</link>
      <guid>https://forem.com/egeriis/hi-im-ronni-egeriis-persson</guid>
      <description>&lt;p&gt;I have been coding for 21 years.&lt;/p&gt;

&lt;p&gt;You can find me on GitHub as &lt;a href="https://github.com/egeriis" rel="noopener noreferrer"&gt;egeriis&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I live in Copenhagen, Denmark.&lt;/p&gt;

&lt;p&gt;I work for Dixie, which I've co-founded. &lt;/p&gt;

&lt;p&gt;I mostly program in these languages: JavaScript &amp;amp; PHP. &lt;/p&gt;

&lt;p&gt;I am currently learning more about websockets and automatic updating of Redux state. &lt;/p&gt;

&lt;p&gt;Nice to meet you.&lt;/p&gt;

</description>
      <category>introduction</category>
    </item>
  </channel>
</rss>
