<?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: Deckstar</title>
    <description>The latest articles on Forem by Deckstar (@deckstar).</description>
    <link>https://forem.com/deckstar</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%2F487662%2Fa5595ddb-53d7-431a-b4b7-a0cf00d2557d.jpeg</url>
      <title>Forem: Deckstar</title>
      <link>https://forem.com/deckstar</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/deckstar"/>
    <language>en</language>
    <item>
      <title>React Pro Tip #2 — How to Type `this.props` to Include `defaultProps`</title>
      <dc:creator>Deckstar</dc:creator>
      <pubDate>Wed, 19 Oct 2022 18:11:46 +0000</pubDate>
      <link>https://forem.com/deckstar/react-pro-tip-2-how-to-type-thisprops-to-include-defaultprops-46l5</link>
      <guid>https://forem.com/deckstar/react-pro-tip-2-how-to-type-thisprops-to-include-defaultprops-46l5</guid>
      <description>&lt;p&gt;This trick is for those occasions when you use a class component, and don't want TypeScript to complain about optional props being possibly &lt;code&gt;undefined&lt;/code&gt;, despite definitely being included in &lt;code&gt;defaultProps&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;In a word, how to fix this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0c244au4ce2x4a30smri.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0c244au4ce2x4a30smri.png" alt="TypeScript might not know the that defaultProps were included"&gt;&lt;/a&gt;Unfortunately, &lt;strong&gt;TypeScript doesn't know that &lt;code&gt;defaultProps&lt;/code&gt; get added to &lt;code&gt;this.props&lt;/code&gt;&lt;/strong&gt;. And so we get &lt;code&gt;Object is possibly 'undefined'.&lt;/code&gt; in places where we shouldn't. &lt;em&gt;Quelle horreur!&lt;/em&gt;&lt;/p&gt;




&lt;p&gt;Contents:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;TLDR&lt;/li&gt;
&lt;li&gt;Explained&lt;/li&gt;
&lt;li&gt;Drawbacks&lt;/li&gt;
&lt;li&gt;Conclusion&lt;/li&gt;
&lt;li&gt;Further reading&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  TLDR
&lt;/h2&gt;

&lt;p&gt;There are two ways to solve this. Both should be simple &amp;amp; easy to understand.&lt;/p&gt;




&lt;h3&gt;
  
  
  Case 1: Simple
&lt;/h3&gt;

&lt;p&gt;If your &lt;code&gt;Props&lt;/code&gt; interface is not used anywhere else, you may want to just remove the optional &lt;code&gt;?:&lt;/code&gt; from the type:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;RatingProps&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="cm"&gt;/**
   * The rating out of 10.
   *
   * @default 10
   */&lt;/span&gt;
  &lt;span class="nl"&gt;rating&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="c1"&gt;// &amp;lt;--- remove the `?`&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As long as the prop is included in the component's &lt;code&gt;defaultProps&lt;/code&gt;, React's typing should be smart enough to not force you to specify the prop when using the component:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Rating&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt; &lt;span class="c1"&gt;// `rating` is required, but we don't need to specify it because it's included in `defaultProps`&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;This is the recommended way to solve this problem&lt;/strong&gt;, if you're writing the code from scratch. This solves the "possibly &lt;code&gt;undefined&lt;/code&gt;" error within the component without creating errors elsewhere, &lt;strong&gt;provided that no other types depend on the &lt;code&gt;Props&lt;/code&gt; interface&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;But if &lt;code&gt;interface Props {}&lt;/code&gt; is already interdependent with other types, and you don't want to refactor them, then you might benefit from the fancier solution below:&lt;/p&gt;




&lt;h3&gt;
  
  
  Case 2: Slightly more complicated
&lt;/h3&gt;

&lt;p&gt;It may be you can't make the &lt;code&gt;props&lt;/code&gt; required, or feel it would be unnecessarily complicated to do so (for example, if many other types depend on the type of your &lt;code&gt;props&lt;/code&gt;). In that case, you can still fix this error.&lt;/p&gt;

&lt;p&gt;All you need is this one-line trick:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Component&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;react&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;RatingProps&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="cm"&gt;/**
   * The rating out of 10.
   *
   * @default 10
   */&lt;/span&gt;
  &lt;span class="nl"&gt;rating&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="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Rating&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;Component&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;RatingProps&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="c1"&gt;// ---------&lt;/span&gt;
  &lt;span class="kr"&gt;declare&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="na"&gt;props&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;RatingProps&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;
    &lt;span class="nb"&gt;Required&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;Pick&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;RatingProps&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kr"&gt;keyof&lt;/span&gt; &lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="nx"&gt;Rating&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;defaultProps&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="c1"&gt;// &amp;lt;--- Add me!&lt;/span&gt;
&lt;span class="c1"&gt;// ---------&lt;/span&gt;

  &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;super&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="nx"&gt;defaultProps&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;rating&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;

  &lt;span class="nf"&gt;render&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&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;rating&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;rating&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;p&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Fail&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/p&amp;gt;&lt;/span&gt;&lt;span class="err"&gt;;
&lt;/span&gt;    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;p&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;rating&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/p&amp;gt;&lt;/span&gt;&lt;span class="err"&gt;;
&lt;/span&gt;  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;Rating&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;(Well, two if you include formatting... 😉)&lt;/p&gt;

&lt;p&gt;This method should be fool-proof: &lt;code&gt;this.props&lt;/code&gt; should now be perfectly typed within the component, and no other side-effects should be produced in any types anywhere else.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fltedqx3txil1dy8gyr9s.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fltedqx3txil1dy8gyr9s.jpg" alt="It is very easy to make TypeScript be able to understand that defaultProps were included in this.props"&gt;&lt;/a&gt;Declare your own &lt;code&gt;props&lt;/code&gt;, and &lt;em&gt;voilà&lt;/em&gt;! Problem solved!&lt;/p&gt;




&lt;h2&gt;
  
  
  Explained
&lt;/h2&gt;

&lt;p&gt;React's &lt;a href="https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/react/index.d.ts#L490" rel="noopener noreferrer"&gt;type definitions file&lt;/a&gt; (&lt;code&gt;index.d.ts&lt;/code&gt;) defines the props as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Readonly&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;P&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;The reason method #1 works, is because of &lt;a href="https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/react/index.d.ts#L3112" rel="noopener noreferrer"&gt;this definition&lt;/a&gt; in the same file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-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;ReactManagedAttributes&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;C&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;P&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;C&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;propTypes&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;T&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nl"&gt;defaultProps&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;D&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;Defaultize&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;MergePropTypes&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;P&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;PropTypes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;InferProps&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;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;D&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;C&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;propTypes&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;T&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;MergePropTypes&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;P&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;PropTypes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;InferProps&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;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;C&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;defaultProps&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;D&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;Defaultize&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;P&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;D&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;P&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;in which React infers the leftover required &lt;code&gt;props&lt;/code&gt; based on the supplied &lt;code&gt;defaultProps&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;Method #2 works because of the following: by declaring our own &lt;code&gt;props&lt;/code&gt; at the top of the component, we simply overwrite React's definition of &lt;code&gt;props&lt;/code&gt; &lt;em&gt;inside the component definition itself&lt;/em&gt; to not only use the &lt;code&gt;P&lt;/code&gt; (i.e., the type of the component's passed in &lt;code&gt;Props&lt;/code&gt;) but also its &lt;code&gt;defaultProps&lt;/code&gt;. (In TypeScript, this is known as a "&lt;a href="https://www.typescriptlang.org/docs/handbook/2/classes.html#type-only-field-declarations" rel="noopener noreferrer"&gt;type-only field declaration&lt;/a&gt;".)&lt;/p&gt;

&lt;p&gt;Pretty neat, huh?&lt;/p&gt;




&lt;p&gt;Another pro-tip: I've actually written a reusable helper type — &lt;code&gt;WithDefaultProps&lt;/code&gt; — to make this trick easier:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="cm"&gt;/**
 * Like `Required`, but you can choose which keys to make required. (`Required` makes all keys required).
 *
 * ---
 *
 * Example:
 * `typescript
 * type Obj = { a?: 1; b?: 2; c?: 3 };
 * type PartiallyRequiredObj = Imposed&amp;lt;Obj, 'a' | 'b'&amp;gt;; // equivalent to `{ a: 1; b: 2; c?: 3 }`;
 * `
 */&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;Imposed&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;K&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="kr"&gt;keyof&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="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;T&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;Required&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;Pick&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;K&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="cm"&gt;/**
 * A helper for React class components with `static defaultProps`.
 *
 * To use, simply add `declare readonly props:` at the top of the class:
 * `ts
 * class MyComponent extends Component&amp;lt;Props&amp;gt;{
 *  declare readonly props: WithDefaultProps&amp;lt;Props, typeof MyComponent.defaultProps&amp;gt;;
 *
 *  // ...
 * }
 * `
 */&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;WithDefaultProps&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;PassedInProps&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;DefaultProps&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nx"&gt;object&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;Readonly&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Imposed&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;PassedInProps&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kr"&gt;keyof&lt;/span&gt; &lt;span class="nx"&gt;DefaultProps&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;
  
  
  Drawbacks
&lt;/h2&gt;

&lt;p&gt;As far as I can tell, there are no drawbacks to either of these methods. (Keep in mind that method #1 is just using React's &lt;code&gt;defaultProps&lt;/code&gt; in a way that's working as intended).&lt;/p&gt;

&lt;p&gt;For the custom &lt;code&gt;props&lt;/code&gt; declaration method, try to keep in mind that you are forcefully overwriting the &lt;code&gt;props&lt;/code&gt;. You must beware of typos which might ruin your type, especially when copy-pasting. Forgetting about this fact might lead to surprises if you don't keep in mind where the types come from.&lt;/p&gt;

&lt;p&gt;Also, note that you have to &lt;em&gt;know&lt;/em&gt; that &lt;code&gt;defaultProps&lt;/code&gt; will definitely be passed in, because TypeScript won't know this. And a React novice might not know that either, so it might be a good reason to add a JSDoc comment over your custom &lt;code&gt;props&lt;/code&gt; declaration. (Not to mention that the seniors will probably wonder what the heck you're doing 😄)&lt;/p&gt;

&lt;p&gt;Otherwise, use it to your heart's content! 🙂&lt;/p&gt;




&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;In this article, we saw two quick &amp;amp; easy ways to make sure that your &lt;code&gt;this.props&lt;/code&gt; always remains type-safe.&lt;/p&gt;

&lt;p&gt;If you're one of the few people still using class components, then this tip may have been helpful for you 😄&lt;/p&gt;




&lt;h2&gt;
  
  
  Further reading:
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;React's &lt;a href="https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/react/index.d.ts" rel="noopener noreferrer"&gt;type definitions file&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;TypeScript's &lt;a href="https://www.typescriptlang.org/docs/handbook/2/classes.html#type-only-field-declarations" rel="noopener noreferrer"&gt;"type-only" field declarations&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>react</category>
      <category>typescript</category>
      <category>cleancode</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>React Pro Tip #1 — Name your `useEffect`!</title>
      <dc:creator>Deckstar</dc:creator>
      <pubDate>Thu, 06 Oct 2022 19:46:58 +0000</pubDate>
      <link>https://forem.com/deckstar/react-pro-tip-1-name-your-useeffect-54ck</link>
      <guid>https://forem.com/deckstar/react-pro-tip-1-name-your-useeffect-54ck</guid>
      <description>&lt;p&gt;There's a very simple trick that will 10x your &lt;code&gt;useEffect&lt;/code&gt; hooks' readability, and probably improve their performance, too: &lt;em&gt;use named functions as callbacks for your &lt;code&gt;useEffect&lt;/code&gt;s&lt;/em&gt;. You might even find that you don't need an effect at all!&lt;/p&gt;




&lt;p&gt;Contents:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;TLDR&lt;/li&gt;
&lt;li&gt;Backstory&lt;/li&gt;
&lt;li&gt;Drawbacks&lt;/li&gt;
&lt;li&gt;Conclusion&lt;/li&gt;
&lt;li&gt;Further reading&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  TLDR
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Do this:
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nx"&gt;useEffect&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;doSomethingAfterMounting&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt; &lt;span class="c1"&gt;// &amp;lt;--- name me!&lt;/span&gt;
    &lt;span class="c1"&gt;// Your effect code &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;h3&gt;
  
  
  Not this:
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nx"&gt;useEffect&lt;/span&gt;&lt;span class="p"&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="cm"&gt;/**
    * Your effect code
    * 
    * Note that this may or may not make
    * sense to you in 6 months time.
    */&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;h3&gt;
  
  
  What for?
&lt;/h3&gt;

&lt;p&gt;This should provide &lt;strong&gt;3 key benefits&lt;/strong&gt;:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;More &lt;em&gt;clarity in the purpose&lt;/em&gt; of the effect, so other programmers would could easily tell what it's supposed to do just by reading the name;&lt;/li&gt;
&lt;li&gt;If the effect throws an error, the &lt;em&gt;function's name will show up in the stack trace&lt;/em&gt;, which should help debugging;&lt;/li&gt;
&lt;li&gt;It should psychologically nudge the programmer into trying to &lt;em&gt;make the effect do only one thing&lt;/em&gt;, and to split different tasks into several &lt;code&gt;useEffects&lt;/code&gt; if necessary;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;But before you even write a &lt;code&gt;useEffect&lt;/code&gt;, &lt;a href="https://beta.reactjs.org/learn/you-might-not-need-an-effect"&gt;consider if you even need one&lt;/a&gt;! There are plenty of situations where using &lt;code&gt;props&lt;/code&gt; directly, or another hook like &lt;code&gt;useMemo&lt;/code&gt; may make much more sense.&lt;/p&gt;




&lt;h2&gt;
  
  
  Backstory
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;useEffect&lt;/code&gt; can be a dangerous hook if you don't know what you're doing. Doubly so because it's usually opaque, with little indication of intent. I can't count how many times I've stared at a giant &lt;code&gt;useEffect&lt;/code&gt; with no idea what it was written to do, or what its authors were thinking.&lt;/p&gt;

&lt;p&gt;Once upon a time, I had to refactor a huge amount of logic for a form page. The original author had used &lt;code&gt;useEffect&lt;/code&gt; in &lt;a href="https://beta.reactjs.org/learn/you-might-not-need-an-effect"&gt;exactly the way that React doesn't recommend&lt;/a&gt;: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;for updating state based on new props,&lt;/li&gt;
&lt;li&gt;for caching,&lt;/li&gt;
&lt;li&gt;for initializing field values,&lt;/li&gt;
&lt;li&gt;for fetching data from an API,&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;... and other bad practices.&lt;/p&gt;

&lt;p&gt;Even worse, he had often written all of that functionality into &lt;em&gt;just one &lt;code&gt;useEffect&lt;/code&gt;&lt;/em&gt;. Clearly, someone had never heard of &lt;a href="https://beta.reactjs.org/apis/react/useMemo"&gt;&lt;code&gt;useMemo&lt;/code&gt;&lt;/a&gt; 😄 There were several &lt;code&gt;useEffects&lt;/code&gt; that stretched to 50 lines or more. Worse yet, there were often several of them in one file, each of which had its own &lt;code&gt;setState&lt;/code&gt; calls that made the effects dependent on each other. One file had 12 such &lt;code&gt;useEffects&lt;/code&gt; (which, side note, is almost certainly far, far too much code for any single component!)&lt;/p&gt;

&lt;p&gt;And alas, that was not the end of it. It turned out that these bad practices were littered throughout the website, on code written by several programmers over many months.&lt;/p&gt;

&lt;p&gt;The refactoring took a week, and while it's nice to have some stable work to do, I'm pretty sure both I and the client would've preferred if I had been doing something more productive.&lt;/p&gt;




&lt;p&gt;It was around that time that I realized that not only is &lt;code&gt;useEffect&lt;/code&gt; very easy to abuse, but that probably the worst part of it was how opaque it was. I was reading Bob Martin's &lt;a href="https://www.goodreads.com/book/show/3735293-clean-code"&gt;Clean Code&lt;/a&gt; around this time, and noticed that this gentleman had some pretty nice tips!&lt;/p&gt;

&lt;p&gt;Among other pearls of wisdom, he advised that:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;all variables (and functions!) should have a clear, informative name:&lt;/li&gt;
&lt;li&gt;functions should be &lt;em&gt;small&lt;/em&gt; and short, aim to &lt;em&gt;do one thing&lt;/em&gt;, have &lt;em&gt;no side effects&lt;/em&gt;, have minimal or &lt;em&gt;no repetition&lt;/em&gt;, and should have &lt;em&gt;separated error handling&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;the best comment is &lt;em&gt;no comment at all&lt;/em&gt; — your code should be &lt;em&gt;self-explanatory&lt;/em&gt; in its intention through its concise logic and good naming&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It was obvious to anyone with eyes that these principles were being woefully neglected in our client's codebase. So as I did my rewrites, I aimed to break up the enormous components with multiple &lt;code&gt;useEffect&lt;/code&gt;s into smaller, easily understandable parts. One file could turn into two, or five, or even ten. This meant having to figure out what all of those giant effects actually did — and to do that, I often pulled out big chunks of logic into their own, shorter functions. &lt;code&gt;fetch()&lt;/code&gt; effects got their own functions, as did &lt;code&gt;moveUI()&lt;/code&gt;, &lt;code&gt;openModal()&lt;/code&gt;, &lt;code&gt;reorderList()&lt;/code&gt; and many others. It turned out that many of these things didn't even need to be effects, and were thus eliminated. &lt;/p&gt;

&lt;p&gt;But other things needed to stay as effects — things like &lt;code&gt;autoClose()&lt;/code&gt; or &lt;code&gt;setHasMounted()&lt;/code&gt;, and I wanted to find a way for these effect hooks to also have names. I aspired to code in a way so that even a person who didn't know how to program (or at least didn't know JavaScript) could see a name and instantly know the point of those few lines.&lt;/p&gt;

&lt;p&gt;Comments wouldn't do, so I started out with the simple idea of using a memoized callback that would get automatically called whenever its dependencies changed:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Idea #1: using a named `useCallback` to add clarity to `useEffect` (don't do this)&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;doSomethingInAnEffect&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useCallback&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="c1"&gt;// ... The effect code&lt;/span&gt;
&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;[])&lt;/span&gt;

&lt;span class="nx"&gt;useEffect&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;doSomethingInAnEffect&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;doSomethingInAnEffect&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This definitely made things better. The effects finally had a meaning, even if they required this superfluous use of a memoized function.&lt;/p&gt;

&lt;p&gt;It was at that point that one day it just struck me like a lightbulb: &lt;em&gt;if all I need is a name, why not just use an old-fashioned named function instead of an arrow function&lt;/em&gt;? It seemed so simple, and why not? We never needed to use &lt;code&gt;this&lt;/code&gt; inside the effect. And then we could avoid the new &lt;code&gt;useCallback&lt;/code&gt;-hell that was festering. Could it really be so simple? I turned to Google, and as it turns out, I wasn't the first person with the idea (see the sources below). And if it's on Twitter, it must be a great idea, right? 😄&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Idea #2: just using an old-fashioned named function (DO do this)&lt;/span&gt;

&lt;span class="nx"&gt;useEffect&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;doSomething&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// insert effect in here&lt;/span&gt;
&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;[])&lt;/span&gt; &lt;span class="c1"&gt;// &amp;lt;-- notice: no extra dependencies! :) &lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As I tried to name my effects, I realized that their names weren't always so obvious — and usually this was because one effect was trying to do too many things. Once I realized this, it became natural to split things apart until each effect did just "one thing" or just got removed completely, and our code quickly got more clearer and simpler as a result. Who knew that naming things well would turn out to be a gift that keeps on giving?&lt;/p&gt;

&lt;p&gt;And so, since then, I've always used named functions whenever I needed &lt;code&gt;useEffect&lt;/code&gt;, and I advise everyone else to do so, too.&lt;/p&gt;




&lt;p&gt;I don't blame my colleagues (whom I also call my friends) for writing messy &lt;code&gt;useEffect&lt;/code&gt;s. I've written plenty of unmaintainable code, too (haven't we all? 😄). Plus, back in those days, we didn't have awesome guidance articles like "&lt;a href="https://beta.reactjs.org/learn/you-might-not-need-an-effect"&gt;You Might Not Need an Effect&lt;/a&gt;" (which I very much recommend you to read, by the way).&lt;/p&gt;

&lt;p&gt;I'd also argue that we had inherited the psychological burden of only having one place for effects — namely, &lt;code&gt;componentDidUpdate&lt;/code&gt; — from back in the days when we only had class components, and this may have nudged us into a "write a giant effect that handles everything"-state of mind that didn't always shake off naturally.&lt;/p&gt;

&lt;p&gt;So what have we learned? I'd say that this experience taught me a few lessons:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Make sure to &lt;em&gt;keep your functions as short as possible&lt;/em&gt;. Ideally, they should do one thing.

&lt;ul&gt;
&lt;li&gt;This tip includes React components, too. If you need to render a giant form, it's probably better to split it up into different files for each section, and maybe even each field.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;useEffect&lt;/code&gt; shouldn't be treated as a "go to solution", and can be dangerous if you don't know what you're doing. To avoid hurting your app's performance, consider if you can get by with just using the &lt;code&gt;prop&lt;/code&gt; itself, or with using &lt;code&gt;useMemo&lt;/code&gt; and &lt;code&gt;useCallback&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;And finally, while naming things may be one of &lt;a href="https://www.karlton.org/2017/12/naming-things-hard/"&gt;the only two hard things in computer science&lt;/a&gt;, it is absolutely vital for the readability of your code.

&lt;ul&gt;
&lt;li&gt;...Which is why you absolutely &lt;em&gt;must&lt;/em&gt; name all of your &lt;code&gt;useEffect&lt;/code&gt;s with named functions! 😉&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Drawbacks
&lt;/h2&gt;

&lt;p&gt;...Are there even any? 😄&lt;/p&gt;

&lt;p&gt;So far, I haven't had any issues with this method, but have certainly felt the benefits.&lt;/p&gt;

&lt;p&gt;One issue I can imagine occurring is pointer mismatches if you use the &lt;code&gt;this&lt;/code&gt; keyword in your effect. Recall that &lt;a href="https://betterprogramming.pub/difference-between-regular-functions-and-arrow-functions-f65639aba256#:~:text=Regular%20functions%20created%20using%20function,be%20used%20as%20constructor%20functions."&gt;arrow functions do not have their own &lt;code&gt;this&lt;/code&gt;, but rather use their parent's &lt;code&gt;this&lt;/code&gt;&lt;/a&gt;. That said, I have never, ever seen &lt;code&gt;this&lt;/code&gt; being used in an effect, or in fact at all in a functional component... so I guess it's a non-issue? 😄&lt;/p&gt;




&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;From what I can see, we should all switch to using named functions in &lt;code&gt;useEffect&lt;/code&gt;, and should do so immediately. This should make our code cleaner and more reliable, and doesn't seem to have any drawbacks. Not only would a simple name let everyone know your intentions, but it should push you to write short, "do only one thing" effects, too.&lt;/p&gt;

&lt;p&gt;What do you think? Let me know in the comments! 🙂 And thanks for reading!&lt;/p&gt;




&lt;h2&gt;
  
  
  Further reading:
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Sergio Xalambrí: &lt;a href="https://sergiodxa.com/articles/pro-tip-name-your-useeffect-functions"&gt;🔥 Pro Tip: Name your useEffect functions&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Cory House: &lt;a href="https://twitter.com/housecor/status/1239622073909161986?lang=en"&gt;Twitter thread about named &lt;code&gt;useEffect&lt;/code&gt;s&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;React documentation: &lt;a href="https://beta.reactjs.org/learn/you-might-not-need-an-effect"&gt;You Might Not Need an Effect&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Robert C. Martin: &lt;a href="https://www.goodreads.com/book/show/3735293-clean-code"&gt;Clean Code: A Handbook of Agile Software Craftsmanship&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Ashutosh Verma: &lt;a href="https://betterprogramming.pub/difference-between-regular-functions-and-arrow-functions-f65639aba256#:~:text=Regular%20functions%20created%20using%20function,be%20used%20as%20constructor%20functions."&gt;The Difference Between Regular Functions and Arrow Functions&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>react</category>
      <category>beginners</category>
      <category>cleancode</category>
      <category>performance</category>
    </item>
    <item>
      <title>How to "Git Copy": copying files while keeping git history</title>
      <dc:creator>Deckstar</dc:creator>
      <pubDate>Tue, 16 Aug 2022 17:14:00 +0000</pubDate>
      <link>https://forem.com/deckstar/how-to-git-copy-copying-files-while-keeping-git-history-1c9j</link>
      <guid>https://forem.com/deckstar/how-to-git-copy-copying-files-while-keeping-git-history-1c9j</guid>
      <description>&lt;p&gt;Have you ever wanted to break a long file into several smaller files, but worried about losing all the &lt;code&gt;git blame&lt;/code&gt; history? Well, with the bash script in this post, you'll be able to split your file into as many files as you want, while still keeping the git history for every single line!&lt;/p&gt;

&lt;blockquote&gt;
&lt;h3&gt;
  
  
  Table of Contents
&lt;/h3&gt;

&lt;p&gt;Motivation&lt;br&gt;
The script&lt;br&gt;
Demo&lt;br&gt;
Pros and cons of this method&lt;br&gt;
Conclusion&lt;br&gt;
Further reading&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Motivation
&lt;/h2&gt;

&lt;p&gt;Why would you ever want to copy a file like this? Basically, &lt;strong&gt;it's useful whenever you want to turn one file into multiple&lt;/strong&gt;, but you still want to git history to stay visible, so people could track the evolution of this file. Not only that, but it ensures that you can also blame, or rather &lt;code&gt;git blame&lt;/code&gt;, the right culprits for... interesting coding decisions 😉&lt;/p&gt;

&lt;p&gt;I can think of two types of situations that I've encountered often:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Sometimes, &lt;strong&gt;a file grows too big to be easily legible and understandable&lt;/strong&gt;. In those cases, it makes sense (and is even recommended) to split it up into smaller chunks.

&lt;ul&gt;
&lt;li&gt;For me, this is a pretty regular thing with React components. It often happens that a small, seemingly simple component grows more and more complex, until there's too much unrelated logic in one place.

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Example&lt;/strong&gt;: a "page" component may start out with a few "sections", and the sections may have their own, complicated logic that's only got something to do with that section. This would be a prime candidate for splitting into multiple files.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Other times, &lt;strong&gt;you might want to turn one file into multiple&lt;/strong&gt;. Perhaps because they have essentially the same functionality.

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Example&lt;/strong&gt;, you may start out developing with one "config" file: &lt;code&gt;config.js&lt;/code&gt;. But as your project gets closer to production-ready, you may realise that you want some different settings for "production" mode, and opt to have two files: &lt;code&gt;config.development.js&lt;/code&gt; and &lt;code&gt;config.production.js&lt;/code&gt;. Regularly copying the config file would make it look like all the production-mode changes happened all at once, whereas "Git copying" the old config would — you guessed it — let other developers track the evolution of the file.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;blockquote&gt;
&lt;h3&gt;
  
  
  Two use cases:
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Splitting a large file into smaller files.&lt;/li&gt;
&lt;li&gt;Creating a copy of a file that will always remain similar to the original.&lt;/li&gt;
&lt;/ol&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  The Script
&lt;/h2&gt;

&lt;p&gt;Without further ado, here's the bash script that you can copy-paste and then use at your own convenience:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

&lt;span class="c"&gt;#!/bin/bash&lt;/span&gt;

&lt;span class="c"&gt;# HOW TO USE:&lt;/span&gt;
&lt;span class="c"&gt;#&lt;/span&gt;
&lt;span class="c"&gt;# PSEUDO-CODE TEMPLATE:&lt;/span&gt;
&lt;span class="c"&gt;# `&lt;/span&gt;
&lt;span class="c"&gt;# bash ./gitCopy.bash {fileToCopy} {...newFiles}&lt;/span&gt;
&lt;span class="c"&gt;# `&lt;/span&gt;
&lt;span class="c"&gt;#&lt;/span&gt;
&lt;span class="c"&gt;# EXAMPLE:&lt;/span&gt;
&lt;span class="c"&gt;# Lets say you have a file called Section.tsx. Your section has grown very big&lt;/span&gt;
&lt;span class="c"&gt;# and you want to split it into into three subsection files, while preserving&lt;/span&gt;
&lt;span class="c"&gt;# the git history. Your plan is to copy the section file into three new files, in&lt;/span&gt;
&lt;span class="c"&gt;# a new subfolder called "subsections".&lt;/span&gt;
&lt;span class="c"&gt;#&lt;/span&gt;
&lt;span class="c"&gt;# In that case, you would do something like this:&lt;/span&gt;
&lt;span class="c"&gt;#&lt;/span&gt;
&lt;span class="c"&gt;# `&lt;/span&gt;
&lt;span class="c"&gt;# bash ./gitCopy.bash ./components/Section.tsx ./components/subsections/Section1.tsx ./components/subsections/Section2.tsx ./components/subsections/Section3.tsx&lt;/span&gt;
&lt;span class="c"&gt;# `&lt;/span&gt;

&lt;span class="nv"&gt;GRAY&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'\033[1;30m'&lt;/span&gt;
&lt;span class="nv"&gt;GREEN&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'\033[0;32m'&lt;/span&gt;
&lt;span class="nv"&gt;LIGHT_BLUE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'\033[1;34m'&lt;/span&gt;
&lt;span class="nv"&gt;RED&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'\033[0;31m'&lt;/span&gt;
&lt;span class="nv"&gt;NO_COLOR&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'\033[0m'&lt;/span&gt;


fail_and_quit &lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;RED&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;Failed to git copy.&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;NO_COLOR&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
    &lt;span class="nb"&gt;exit &lt;/span&gt;0
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt; &lt;span class="se"&gt;\(&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$1&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="nt"&gt;-a&lt;/span&gt; &lt;span class="nv"&gt;$# &lt;/span&gt;&lt;span class="nt"&gt;-ge&lt;/span&gt; 2 &lt;span class="se"&gt;\)&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
    &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;RED&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;Invalid inputs&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;NO_COLOR&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;

    &lt;span class="nb"&gt;cat &lt;/span&gt;1&amp;gt;&amp;amp;2 &lt;span class="o"&gt;&amp;lt;&amp;lt;-&lt;/span&gt;&lt;span class="no"&gt;EOF&lt;/span&gt;&lt;span class="sh"&gt;
    Usage: &lt;/span&gt;&lt;span class="se"&gt;\$&lt;/span&gt;&lt;span class="sh"&gt;0 ORIGINAL copy1 [... copyN]

    Copy ORIGINAL, preserving history for git blame
    New history will have N+3 commits
&lt;/span&gt;&lt;span class="no"&gt;
    EOF
&lt;/span&gt;    &lt;span class="nb"&gt;exit &lt;/span&gt;1
&lt;span class="k"&gt;fi

&lt;/span&gt;&lt;span class="nv"&gt;ORIGINAL&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$1&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c"&gt;# shift to $2 and start counting arguments from 2&lt;/span&gt;
&lt;span class="nb"&gt;shift&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c"&gt;# Messages&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;Will copy &lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;GRAY&lt;/span&gt;&lt;span class="k"&gt;}${&lt;/span&gt;&lt;span class="nv"&gt;ORIGINAL&lt;/span&gt;&lt;span class="k"&gt;}${&lt;/span&gt;&lt;span class="nv"&gt;NO_COLOR&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; into &lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;LIGHT_BLUE&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;+&lt;/span&gt;&lt;span class="nv"&gt;$# &lt;/span&gt;&lt;span class="s2"&gt;files&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;NO_COLOR&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;:"&lt;/span&gt;

&lt;span class="nv"&gt;args&lt;/span&gt;&lt;span class="o"&gt;=(&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$@&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;for &lt;/span&gt;i &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="p"&gt;!args[@]&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;do
   &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="s2"&gt;"    &lt;/span&gt;&lt;span class="nv"&gt;$i&lt;/span&gt;&lt;span class="s2"&gt;. &lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;GRAY&lt;/span&gt;&lt;span class="k"&gt;}${&lt;/span&gt;&lt;span class="nv"&gt;args&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;$i&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="k"&gt;}${&lt;/span&gt;&lt;span class="nv"&gt;NO_COLOR&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="k"&gt;done

&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="s2"&gt;"New history will have &lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;GREEN&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;+&lt;/span&gt;&lt;span class="k"&gt;$((&lt;/span&gt;&lt;span class="nv"&gt;$# &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="m"&gt;3&lt;/span&gt;&lt;span class="k"&gt;))&lt;/span&gt;&lt;span class="s2"&gt; commits &lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;NO_COLOR&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="c"&gt;# /Messages&lt;/span&gt;

&lt;span class="nv"&gt;NEWLINE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;$'&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s1"&gt;'&lt;/span&gt;
&lt;span class="nv"&gt;KEEP&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;mkdir&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; &lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;dirname&lt;/span&gt; &lt;span class="nv"&gt;$1&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;mktemp&lt;/span&gt; ./&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$1&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;.XXXXXXXX&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nv"&gt;MESSAGE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"Copied (with git history):&lt;/span&gt;&lt;span class="nv"&gt;$NEWLINE$NEWLINE$ORIGINAL$NEWLINE$NEWLINE&lt;/span&gt;&lt;span class="s2"&gt; — into: —&lt;/span&gt;&lt;span class="nv"&gt;$NEWLINE$NEWLINE$@&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="nv"&gt;SPLIT&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;""&lt;/span&gt;

&lt;span class="c"&gt;# Remember current commit&lt;/span&gt;
&lt;span class="nv"&gt;ROOT&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;git rev-parse HEAD&lt;span class="si"&gt;)&lt;/span&gt;

&lt;span class="c"&gt;# Check for errors&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="nt"&gt;-z&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$ORIGINAL&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
    &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;RED&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;ERROR:&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;NO_COLOR&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; Did not get ORIGINAL variable."&lt;/span&gt;
    fail_and_quit
&lt;span class="k"&gt;elif&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="nt"&gt;-z&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$KEEP&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
    &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;RED&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;ERROR:&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;NO_COLOR&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; Did not get KEEP variable."&lt;/span&gt;
    fail_and_quit
&lt;span class="k"&gt;elif&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="nt"&gt;-z&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$MESSAGE&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
    &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;RED&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;ERROR:&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;NO_COLOR&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; Did not get MESSAGE variable."&lt;/span&gt;
    fail_and_quit
&lt;span class="k"&gt;fi&lt;/span&gt;


&lt;span class="c"&gt;# Create branch where $2 has $ORIGINAL's history&lt;/span&gt;
&lt;span class="k"&gt;for &lt;/span&gt;f &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$@&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;do
    &lt;/span&gt;git reset &lt;span class="nt"&gt;--soft&lt;/span&gt; &lt;span class="nv"&gt;$ROOT&lt;/span&gt;
    git checkout &lt;span class="nv"&gt;$ROOT&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$ORIGINAL&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
    git &lt;span class="nb"&gt;mv&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$ORIGINAL&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$f&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
    git commit &lt;span class="nt"&gt;-n&lt;/span&gt; &lt;span class="nt"&gt;-m&lt;/span&gt; &lt;span class="s2"&gt;"* (create &lt;/span&gt;&lt;span class="nv"&gt;$f&lt;/span&gt;&lt;span class="s2"&gt;)&lt;/span&gt;&lt;span class="nv"&gt;$NEWLINE$NEWLINE$MESSAGE&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
    &lt;span class="nv"&gt;SPLIT&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;git rev-parse HEAD&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$SPLIT&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="k"&gt;done&lt;/span&gt;

&lt;span class="c"&gt;# Go back to initial branch and move $ORIGINAL out of the way&lt;/span&gt;
git reset &lt;span class="nt"&gt;--hard&lt;/span&gt; HEAD^
git &lt;span class="nb"&gt;mv&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$ORIGINAL&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$KEEP&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
git commit &lt;span class="nt"&gt;-n&lt;/span&gt; &lt;span class="nt"&gt;-m&lt;/span&gt; &lt;span class="s2"&gt;"* (keep &lt;/span&gt;&lt;span class="nv"&gt;$ORIGINAL&lt;/span&gt;&lt;span class="s2"&gt;)&lt;/span&gt;&lt;span class="nv"&gt;$NEWLINE$NEWLINE$MESSAGE&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;

&lt;span class="c"&gt;# Merge $2's branch back into the original&lt;/span&gt;
git merge &lt;span class="nv"&gt;$SPLIT&lt;/span&gt; &lt;span class="nt"&gt;-m&lt;/span&gt; &lt;span class="s2"&gt;"* (merge)&lt;/span&gt;&lt;span class="nv"&gt;$NEWLINE$NEWLINE$MESSAGE&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
git commit &lt;span class="nt"&gt;-a&lt;/span&gt; &lt;span class="nt"&gt;-n&lt;/span&gt; &lt;span class="nt"&gt;-m&lt;/span&gt; &lt;span class="s2"&gt;"* (merge)&lt;/span&gt;&lt;span class="nv"&gt;$NEWLINE$NEWLINE$MESSAGE&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;

&lt;span class="c"&gt;# Move $ORIGINAL back where it was&lt;/span&gt;
git &lt;span class="nb"&gt;mv&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$KEEP&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$ORIGINAL&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
git commit &lt;span class="nt"&gt;-n&lt;/span&gt; &lt;span class="nt"&gt;-m&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$MESSAGE&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;


&lt;span class="c"&gt;# Report&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;New history: &lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;GRAY&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;git rev-parse &lt;span class="nt"&gt;--short&lt;/span&gt; &lt;span class="nv"&gt;$ROOT&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;..&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;git rev-parse &lt;span class="nt"&gt;--short&lt;/span&gt; HEAD&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;NO_COLOR&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;GREEN&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;Success!&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;NO_COLOR&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="nb"&gt;exit &lt;/span&gt;0



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

&lt;/div&gt;
&lt;p&gt;I usually title this thing &lt;code&gt;gitCopy.bash&lt;/code&gt;. But in principle you could call it whatever you want.&lt;/p&gt;

&lt;p&gt;Note as well that a lot of code in here is just UI fluff (in particular, most of the logic with the color- &amp;amp; text-related variables is completely unnecessary to achieve the core functionality). You don't really need all the colorful messages to show up in your terminal when running this script. But I just think that they're nice to have 😉&lt;/p&gt;
&lt;h2&gt;
  
  
  Demo
&lt;/h2&gt;

&lt;p&gt;As you can see in the GIF below, this script should be pretty easy to use:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fr8h8zgpcyfty2kcl76q6.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fr8h8zgpcyfty2kcl76q6.gif" alt="Demo of the "&gt;&lt;/a&gt;Demo of the "gitCopy" script.&lt;br&gt;
Notice how both files show the same &lt;code&gt;git blame&lt;/code&gt; information, using VS Code's &lt;a href="https://marketplace.visualstudio.com/items?itemName=eamodio.gitlens" rel="noopener noreferrer"&gt;GitLens&lt;/a&gt; extension.&lt;/p&gt;
&lt;h2&gt;
  
  
  Pros and cons of this method
&lt;/h2&gt;
&lt;h3&gt;
  
  
  Advantages:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Your &lt;strong&gt;git history gets kept in every file&lt;/strong&gt;;

&lt;ul&gt;
&lt;li&gt;You and others will be able to easily see the &lt;code&gt;git blame&lt;/code&gt; records and track how the file changed and why&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;It's &lt;strong&gt;very easy to use&lt;/strong&gt; — just copy a file path, then decide on one or more new ones, press enter and voilà!&lt;/li&gt;
&lt;li&gt;If you change your mind, &lt;strong&gt;you can always revert the commits&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Disadvantages:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;This method uses the "octopus-merge" strategy between the temporary branches, which means that &lt;strong&gt;your git history will no longer be a perfectly straight line&lt;/strong&gt;.

&lt;ul&gt;
&lt;li&gt;You probably don't care about this, but there do exist &lt;a href="https://www.bitsnbites.eu/a-tidy-linear-git-history/" rel="noopener noreferrer"&gt;arguments for keeping &lt;code&gt;git log --graph&lt;/code&gt; linear&lt;/a&gt;, as well as &lt;a href="https://stackoverflow.com/a/52864608" rel="noopener noreferrer"&gt;counterarguments&lt;/a&gt; against it. Personally, I've done both, but I don't really have much of an opinion on this.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;This method &lt;strong&gt;creates a lot of commits&lt;/strong&gt;, which can be a bit frustrating. 

&lt;ul&gt;
&lt;li&gt;How many commits? Well, it's &lt;code&gt;N + 3&lt;/code&gt; for every file that you want to copy, where &lt;code&gt;N&lt;/code&gt; is the number of copies that you want to make.

&lt;ul&gt;
&lt;li&gt;So, for example, let's say that you want to copy two different files, with 1 copy of the first file and 3 copies of the second file. For instance, maybe you want to copy &lt;code&gt;config.js&lt;/code&gt; into &lt;code&gt;config.production.js&lt;/code&gt;,  and you want to copy &lt;code&gt;Component.tsx&lt;/code&gt; into &lt;code&gt;Subcomponent1.tsx&lt;/code&gt;, &lt;code&gt;Subcomponent2.tsx&lt;/code&gt; and &lt;code&gt;Subcomponent3.tsx&lt;/code&gt;. That would mean 1 + 3 = 4 commits for the &lt;code&gt;config&lt;/code&gt; file, and 3 + 3 = 6 commits for the &lt;code&gt;Component&lt;/code&gt;. Plus at least 1 more commit if you want to actually edit your new files, bringing the total up to at least 11. That's a lot of commits!&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;The general formula here is: 

&lt;div class="katex-element"&gt;
  &lt;span class="katex-display"&gt;&lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;∑Cf=(N1+3)+(N2+3)...+(Nf+3)\sum C_f = (N_1 + 3) + (N_2 + 3) ... + (N_f + 3)&lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mop op-symbol large-op"&gt;∑&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;C&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mathnormal mtight"&gt;f&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;=&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mopen"&gt;(&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;N&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mtight"&gt;1&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mbin"&gt;+&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;3&lt;/span&gt;&lt;span class="mclose"&gt;)&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mbin"&gt;+&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mopen"&gt;(&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;N&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mtight"&gt;2&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mbin"&gt;+&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;3&lt;/span&gt;&lt;span class="mclose"&gt;)&lt;/span&gt;&lt;span class="mord"&gt;...&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mbin"&gt;+&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mopen"&gt;(&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;N&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mathnormal mtight"&gt;f&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mbin"&gt;+&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;3&lt;/span&gt;&lt;span class="mclose"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/div&gt;

&lt;p&gt;where:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;span class="katex-element"&gt;
  &lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;∑Cf\sum C_f&lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mop op-symbol small-op"&gt;∑&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;C&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mathnormal mtight"&gt;f&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;
 is the sum total of the number of commits that you will create by copying all the 
&lt;span class="katex-element"&gt;
  &lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;ff&lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;f&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;
 files, and&lt;/li&gt;
&lt;li&gt;
&lt;span class="katex-element"&gt;
  &lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;NiN_i&lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;N&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mathnormal mtight"&gt;i&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;
 is the number of copies that you want to create of each file 
&lt;span class="katex-element"&gt;
  &lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;ii&lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;i&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;
.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;We can see that the minimum number of commits here is 4 (when copying one file one time).&lt;/li&gt;

&lt;li&gt;This large number of commits may start to feel overwhelming when reading commit histories, or when reading through pull requests.&lt;/li&gt;

&lt;/ul&gt;

&lt;/li&gt;

&lt;/ul&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;So that's "git copying" in a nutshell.&lt;/p&gt;

&lt;p&gt;We've seen that this method is an easy and flexible way to keep git history while copying files. However, we've also seen that it produces a lot of commits, and requires an "octopus merge" strategy, which may not be ideal in some teams.&lt;/p&gt;

&lt;p&gt;As always with coding tools, you will have to decide for yourself when and whether to use this new trick that I have just presented to you 🙂&lt;/p&gt;

&lt;p&gt;Good luck and happy coding!&lt;/p&gt;




&lt;h2&gt;
  
  
  Further reading
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Raymond Chen's &lt;a href="https://devblogs.microsoft.com/oldnewthing/20190916-00/?p=102892" rel="noopener noreferrer"&gt;blog post&lt;/a&gt; (2019) about splitting files while keeping git history, using a sequence of new file names and new git branches.&lt;/li&gt;
&lt;li&gt;David Sherman's &lt;a href="https://gitlab.inria.fr/-/snippets/520" rel="noopener noreferrer"&gt;Gitlab snippet&lt;/a&gt; (2019) documenting a bash script which that automatically copies a file as many times as needed to to new files, which served as the main inspiration for the script in this post.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>git</category>
      <category>bash</category>
      <category>productivity</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Gatsby JS — How to solve FOUC when using tss-react and Material UI v5</title>
      <dc:creator>Deckstar</dc:creator>
      <pubDate>Sat, 29 Jan 2022 17:01:36 +0000</pubDate>
      <link>https://forem.com/deckstar/gatsby-js-how-to-solve-fouc-when-using-tss-react-and-material-ui-v5-465f</link>
      <guid>https://forem.com/deckstar/gatsby-js-how-to-solve-fouc-when-using-tss-react-and-material-ui-v5-465f</guid>
      <description>&lt;p&gt;&lt;a href="https://mui.com"&gt;Material UI&lt;/a&gt; v5 brought some amazing updates, but switching from &lt;a href="https://cssinjs.org"&gt;JSS&lt;/a&gt; to &lt;a href="https://emotion.sh/docs/introduction"&gt;Emotion&lt;/a&gt; had an arguably nasty side-effect: it was no longer as straightforward to group your component styles in classes. Fortunately, a fantastic library emerged that allowed developers to not only reduce the extreme pain from migrating all their classes from v4's &lt;code&gt;makeStyles&lt;/code&gt; to emotion, but to also to continue to writing classes in practically the same syntax, with wonderful TS type-safety. This library was &lt;a href="https://github.com/garronej/tss-react/"&gt;tss-react&lt;/a&gt;, and it was one of my favorite open source discoveries of 2021.&lt;/p&gt;

&lt;p&gt;Unfortunately, however, &lt;code&gt;tss-react&lt;/code&gt; and &lt;code&gt;material-ui&lt;/code&gt; don't exactly work "out of the box" when it comes to &lt;a href="https://www.gatsbyjs.com"&gt;Gatsby JS&lt;/a&gt;. Gatsby is a fantastic framework for generating static websites with React code. Static websites are great because they load fast, can be largely cached in a visitor's browser and have great Search Engine Optimization (SEO).&lt;/p&gt;

&lt;p&gt;The trouble I was having was that my production website was displaying what is known as a &lt;a href="https://en.wikipedia.org/wiki/Flash_of_unstyled_content"&gt;"flash of unseen content"&lt;/a&gt;, or FOUC. Material UI users have known about this problem for a long time — in fact, there even exists a &lt;a href="https://github.com/hupe1980/gatsby-plugin-material-ui/"&gt;popular plugin&lt;/a&gt; for solving this exact issue.&lt;/p&gt;

&lt;p&gt;But because &lt;code&gt;tss-react&lt;/code&gt; and &lt;code&gt;material-ui&lt;/code&gt; do not share the same &lt;code&gt;emotion&lt;/code&gt; cache, then simply adding &lt;code&gt;gatsby-plugin-material-ui&lt;/code&gt; doesn't work. A more custom solution is needed.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;This post is about how I solved the FOUC-problem in my Gatsby JS website after migrating to Material UI v5 with &lt;code&gt;tss-react&lt;/code&gt;.&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  TLDR:
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;copy paste the two files below&lt;/li&gt;
&lt;li&gt;make sure your &lt;code&gt;&amp;lt;CacheProvider /&amp;gt;&lt;/code&gt; component imports your emotion cache from the new place&lt;/li&gt;
&lt;li&gt;remove &lt;code&gt;gatsby-plugin-material-ui&lt;/code&gt; from your &lt;code&gt;gatsby-node.js&lt;/code&gt; file if you had it&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Showcase:
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Here's a &lt;a href="https://github.com/Deckstar/gatsby-tss-example"&gt;sample implementation&lt;/a&gt;.&lt;/strong&gt; Feel free to copy from it! 😉&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This little example project should be helpful if you get stuck 🙂&lt;/p&gt;




&lt;h2&gt;
  
  
  Explained
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Step 1: make an emotion &lt;code&gt;cache&lt;/code&gt; that can be used both on the client and the server
&lt;/h3&gt;

&lt;p&gt;This is the cache that will be used by emotion to make your Material UI styles.&lt;/p&gt;

&lt;p&gt;Unfortunately, you probably want this file to be a vanilla JS file, without TypeScript. This is because the &lt;code&gt;gatsby-srr.js&lt;/code&gt; file that we will have to create later must be a vanilla JS file, and cannot parse uncompiled TypeScript. But don't worry — you can still get some TS typing intellisense just by adding a few JSDoc comments! ;)&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;// ./src/theme/cache.js&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;createCache&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@emotion/cache&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="cm"&gt;/** @type {import('@emotion/cache').Options} */&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;cacheProps&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;mui&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;prepend&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="cm"&gt;/** @type {import("@emotion/cache").EmotionCache | undefined} */&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;muiCache&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;makeMuiCache&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="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;muiCache&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;muiCache&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;createCache&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;cacheProps&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;muiCache&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;Don't forget to use this cache for your &lt;code&gt;&amp;lt;CacheProvider /&amp;gt;&lt;/code&gt; that wraps your Material UI &lt;code&gt;&amp;lt;ThemeProvider /&amp;gt;&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// example&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;makeMuiCache&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="s1"&gt;./cache&lt;/span&gt;&lt;span class="dl"&gt;'&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;muiCache&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;makeMuiCache&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;ThemeWrapper&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;children&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ReactNode&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="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;children&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;props&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="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;CacheProvider&lt;/span&gt;
        &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;muiCache&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="c1"&gt;// &amp;lt;-- use the new cache here&lt;/span&gt;
    &lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;ThemeProvider&lt;/span&gt; &lt;span class="na"&gt;theme&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;yourTheme&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;children&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;ThemeProvider&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;CacheProvider&lt;/span&gt;&lt;span class="p"&gt;&amp;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;h3&gt;
  
  
  Step 2: create a &lt;code&gt;gatsby-srr.js&lt;/code&gt; file, and add the generated styles to the server-side &lt;code&gt;&amp;lt;head&amp;gt;&lt;/code&gt;-components
&lt;/h3&gt;

&lt;p&gt;You'll probably want it to look something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// ./gatsby-srr.js&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;CacheProvider&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="s1"&gt;@emotion/react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;createEmotionServer&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@emotion/server/create-instance&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&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;renderToString&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="s1"&gt;react-dom/server&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&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;getTssDefaultEmotionCache&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="s1"&gt;tss-react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&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;makeMuiCache&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="s1"&gt;./src/theme/cache&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="cm"&gt;/** @param {import('gatsby').ReplaceRendererArgs} args */&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;replaceRenderer&lt;/span&gt; &lt;span class="o"&gt;=&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="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&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;bodyComponent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;replaceBodyHTMLString&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setHeadComponents&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;args&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;muiCache&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;makeMuiCache&lt;/span&gt;&lt;span class="p"&gt;();&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;extractCriticalToChunks&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;createEmotionServer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;muiCache&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;emotionStyles&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;extractCriticalToChunks&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nx"&gt;renderToString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;CacheProvider&lt;/span&gt; &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;muiCache&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;bodyComponent&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;CacheProvider&lt;/span&gt;&lt;span class="p"&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;muiStyleTags&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;emotionStyles&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;styles&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;style&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="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;css&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;ids&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;style&lt;/span&gt; &lt;span class="o"&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="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;style&lt;/span&gt;
        &lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
        &lt;span class="na"&gt;data-emotion&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;ids&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;` `&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
        &lt;span class="na"&gt;dangerouslySetInnerHTML&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;__html&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;css&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
      &lt;span class="p"&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;tssCache&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;getTssDefaultEmotionCache&lt;/span&gt;&lt;span class="p"&gt;();&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;extractCritical&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;createEmotionServer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;tssCache&lt;/span&gt;&lt;span class="p"&gt;);&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;css&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;ids&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;extractCritical&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;renderToString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;bodyComponent&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;tssStyleTag&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;style&lt;/span&gt;
      &lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"tss-styles"&lt;/span&gt;
      &lt;span class="na"&gt;data-emotion&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;`css &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;ids&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt; &lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
      &lt;span class="na"&gt;dangerouslySetInnerHTML&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;__html&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;css&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;/&amp;gt;&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;combinedStyleTags&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[...&lt;/span&gt;&lt;span class="nx"&gt;muiStyleTags&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;tssStyleTag&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
  &lt;span class="nx"&gt;setHeadComponents&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;combinedStyleTags&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="c1"&gt;// render the result from `extractCritical`&lt;/span&gt;
  &lt;span class="nx"&gt;replaceBodyHTMLString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;emotionStyles&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;html&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;The idea here is that we are exporting a &lt;code&gt;replaceRenderer&lt;/code&gt; function that Gatsby will use internally to render your page when generating it (see Gatsby the docs &lt;a href="https://www.gatsbyjs.com/docs/reference/config-files/gatsby-ssr/#replaceRenderer"&gt;here&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;The first part of this function is &lt;a href="https://github.com/hupe1980/gatsby-plugin-material-ui/blob/master/gatsby-plugin-material-ui/src/gatsby-ssr.js"&gt;copy-pasted straight out of &lt;code&gt;gatsby-plugin-material-ui&lt;/code&gt; &lt;/a&gt;. However, where the plugin has to use clever file-system tricks to get access to your emotion cache, we can just import our own cache directly! With our cache available from our &lt;code&gt;makeMuiCache&lt;/code&gt; function, we can easily generate our &lt;code&gt;muiStyleTags&lt;/code&gt; using emotions server-side helpers.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;tss-react&lt;/code&gt; is also very helpful — you can easily access its emotion cache using the &lt;code&gt;getTssDefaultEmotionCache&lt;/code&gt; helper. As &lt;a href="https://ntsim.uk/posts/how-to-add-vanilla-emotion-ssr-to-gatsby"&gt;Nicholas Tsim documents in his blog post&lt;/a&gt;, it is then very easy to create the style tags for any emotion cache — much like how we did earlier for Material UI, we create another emotion server, extract the critical CSS and map it convert it into a JSX style tag.&lt;/p&gt;

&lt;p&gt;We then combine all our style tags into one array, and use the Gatsby &lt;code&gt;setHeadComponents&lt;/code&gt; helper so that all of them would be included on our page. And finally, we call &lt;code&gt;replacebodyhtml&lt;/code&gt; with the generated HTML-string.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 3: Remove &lt;code&gt;gatsby-plugin-material-ui&lt;/code&gt; from &lt;code&gt;gatsby-config.js&lt;/code&gt; to avoid conflicts.
&lt;/h3&gt;

&lt;p&gt;Self-explanatory. If you were using the plugin before, then open your Gatsby config and delete it:&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;// ./gatsby-config.js&lt;/span&gt;

&lt;span class="nx"&gt;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exports&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
 &lt;span class="cm"&gt;/* Your site config here */&lt;/span&gt;
 &lt;span class="na"&gt;plugins&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
   &lt;span class="s2"&gt;`gatsby-plugin-material-ui`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// &amp;lt;-- delete me!&lt;/span&gt;
    &lt;span class="c1"&gt;// ...rest plugins&lt;/span&gt;
 &lt;span class="p"&gt;],&lt;/span&gt;
 &lt;span class="c1"&gt;// ...rest config&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;Don't forget to run &lt;code&gt;yarn remove gatsby-plugin-material-ui&lt;/code&gt; (or the same command with whatever package manager you're using), since the package is no longer needed.&lt;/p&gt;




&lt;p&gt;That's it! Your Gatsby site should now load without any flash of unseen content, and you can continue to use the spectacular Material UI library in all its v5 glory, together with &lt;code&gt;tss-react&lt;/code&gt;, of course ;)&lt;/p&gt;

&lt;p&gt;Good luck!&lt;/p&gt;

</description>
      <category>fouc</category>
      <category>tssreact</category>
      <category>materialui</category>
      <category>gatsby</category>
    </item>
    <item>
      <title>TypeScript &amp; VS Code tricks for beginners: 10 things I wish I knew when starting out</title>
      <dc:creator>Deckstar</dc:creator>
      <pubDate>Sat, 29 Jan 2022 14:24:04 +0000</pubDate>
      <link>https://forem.com/deckstar/typescript-vs-code-tricks-for-beginners-10-things-i-wish-i-knew-when-starting-out-15la</link>
      <guid>https://forem.com/deckstar/typescript-vs-code-tricks-for-beginners-10-things-i-wish-i-knew-when-starting-out-15la</guid>
      <description>&lt;p&gt;TypeScript is supposed to make your development life easier, but I vividly recall my earliest memories of TypeScript involving a lot of cursing, confusion about errors, and wondering why anyone would ever waste time writing out all types and how interfaces were any better than PropTypes. I used to write type definitions for hours and complain that I definitely didn't feel my productivity getting any better.&lt;/p&gt;

&lt;p&gt;My point of view was understandable: I was a total noob (or, in polite parlance, a beginner). And everything is hard and demoralizing when you're a noob. Today, I love TypeScript and usually find projects written in plain old JavaScript to be injurious to my mental health. Looking back, I probably hated TypeScript early on because of all the hurdles I had to go through until I could feel its benefits.&lt;/p&gt;

&lt;p&gt;If you've recently joined a TypeScript project, or are thinking of learning it for your own work, then I hope that my little blog post will help make your transition a little easier. These are probably the things that I wish I had known when starting out with TypeScript, but nobody showed me.&lt;/p&gt;

&lt;p&gt;Without further ado, here's a list of of cool &amp;amp; useful tricks that make your life way easier when working with TypeScript.&lt;/p&gt;




&lt;h3&gt;
  
  
  1. Use &lt;code&gt;Ctrl + Space&lt;/code&gt; to see all the available props of a component, or all the available keys of an object.
&lt;/h3&gt;

&lt;p&gt;Don't be a noob. Switching between files or Googling documentation is for people who've got nothing better to do with their time ;) It's much easier to see all available variables immediately, in a drop down menu right under your code.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F46qnunzqm36ouwy3zt4i.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F46qnunzqm36ouwy3zt4i.png" alt="Image description"&gt;&lt;/a&gt;Much more helpful than having 20 Chrome tabs open, right?&lt;/p&gt;

&lt;p&gt;If you're dealing with popular libraries, 9 times out of 10 the variable name will be descriptive enough for you to know what it's supposed to be used for. If you're confused by the function of a variable in your own code (or your colleague's code!), then you'll see immediately which variables may need to be renamed, or even refactored.&lt;/p&gt;




&lt;h3&gt;
  
  
  2. Use &lt;code&gt;as&lt;/code&gt; when you know the type of your variable better than your linter.
&lt;/h3&gt;

&lt;p&gt;It happens to all of us. You try to pass in a variable that may be a string, TypeScript screams at you that it may also be undefined, which is unacceptable. But you know for a fact that this variable will never be undefined where you're using it, because you controlled for that ages ago. And perhaps you don't want to write a slew of if-statements.&lt;/p&gt;

&lt;p&gt;The easy solution is to just use &lt;code&gt;as&lt;/code&gt;:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;

&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;Props&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;word&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// let's say that we definitely passed in&lt;/span&gt;
&lt;span class="c1"&gt;// a word to props in another file&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;word&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;props&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;logWord&lt;/span&gt; &lt;span class="o"&gt;=&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="kr"&gt;string&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="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`The word is: &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;`&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// woops, Typescript error! word is required!&lt;/span&gt;
&lt;span class="nf"&gt;logWord&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="c1"&gt;// no error&lt;/span&gt;
&lt;span class="nf"&gt;logWord&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;word&lt;/span&gt; &lt;span class="k"&gt;as&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;The example above may make it look like using &lt;code&gt;as&lt;/code&gt; would have to be bad practice. Why make the prop optional if you need to use it later? True, but that's only because I couldn't think of a better example. In fact, this issue pops up quite often, &lt;em&gt;especially&lt;/em&gt; when working with 3rd party libraries.&lt;/p&gt;

&lt;p&gt;Sooner or later, you will probably encounter a situation in which it's useful to have &lt;code&gt;as&lt;/code&gt; in your mental toolkit, and in which using &lt;code&gt;as&lt;/code&gt; solves the problem 5 times faster than if you insisted on making your code logic absolutely foolproof and TypeScript-friendly.&lt;/p&gt;

&lt;p&gt;Using &lt;code&gt;as&lt;/code&gt; is called &lt;em&gt;type-assertion&lt;/em&gt;, and it can also be done by putting the type in brackets before the variable:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;

&lt;span class="c1"&gt;// type assertion with 'as'&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;wordLength&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;word&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// type assertion with brackets&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;wordLength&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;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="nx"&gt;word&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;


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

&lt;/div&gt;




&lt;h3&gt;
  
  
  3. Use &lt;code&gt;Pick&lt;/code&gt; and &lt;code&gt;Omit&lt;/code&gt; to efficiently create typed sub-components
&lt;/h3&gt;

&lt;p&gt;Writing interfaces for every sub-component is repeating yourself. And as every clever software book will tell you, the first rule of programming is Don't Repeat Yourself!&lt;/p&gt;

&lt;p&gt;Try this:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;


&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;PersonProps&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;age&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="nx"&gt;imageUrl&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;location&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&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;PersonContainer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;PersonProps&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="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="nx"&gt;age&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;imageUrl&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;location&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;description&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;props&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="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;img&lt;/span&gt; &lt;span class="nx"&gt;src&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;imageUrl&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;h2&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;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;age&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/h2&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;h3&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;location&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/h3&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;p&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;description&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/p&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&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="cm"&gt;/**
* Let's say you only want to display some of the 
* person's info in a summary card, which can be 
* pressed for details
*/&lt;/span&gt;
&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;CardProps&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Pick&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;PersonProps&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;name&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;age&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;imageUrl&lt;/span&gt;&lt;span class="dl"&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;PotentialRomanticInterest&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;CardProps&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="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="nx"&gt;age&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;imageUrl&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;props&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="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;img&lt;/span&gt; &lt;span class="nx"&gt;src&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;imageUrl&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;h2&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;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;age&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/h2&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&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="cm"&gt;/**
* What if you've got a lot of props, but you want
* to leave some out?
* 
* You can make a new type/interface with all 
* the same props as your other interface (here, 
* PersonProps), but with some omitted.
*/&lt;/span&gt;
&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;BlindDateProfile&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Omit&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;PersonProps&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;imageUrl&lt;/span&gt;&lt;span class="dl"&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;PotentialRomanticInterest&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;BlindDateProfile&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="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="nx"&gt;age&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;location&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;description&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;props&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="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;img&lt;/span&gt; &lt;span class="nx"&gt;src&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="s1"&gt;images/incognito-image.png&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;h2&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;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;age&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/h2&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;h3&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;location&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/h3&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;p&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;description&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/p&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;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;There's more selectors where that came from. &lt;code&gt;Pick&lt;/code&gt; and &lt;code&gt;Omit&lt;/code&gt; may be the simplest and most common, but there are plenty of other useful ones, like &lt;code&gt;Record&lt;/code&gt;, &lt;code&gt;Partial&lt;/code&gt;, or &lt;code&gt;Parameters&lt;/code&gt;. If you want to dive deeper, check out &lt;a href="https://www.typescriptlang.org/docs/handbook/utility-types.html" rel="noopener noreferrer"&gt;TypeScript's Utility types&lt;/a&gt; documentation.&lt;/p&gt;




&lt;h3&gt;
  
  
  4. &lt;code&gt;Cmd + click&lt;/code&gt; on things to explore what they expect.
&lt;/h3&gt;

&lt;p&gt;All right, this isn't really a TypeScript trick. But a typical TS developer probably spends a lot of time command-clicking his various 3rd party library functions. With 3rd party libraries, I often find it much easier to figure out what various parameters of a function are for by just clicking around the TypeScript definitions, instead of reading the documentation.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fscaqz8hw8mr8t44plmw7.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fscaqz8hw8mr8t44plmw7.gif" alt="Image description"&gt;&lt;/a&gt;&lt;code&gt;Cmd + click&lt;/code&gt; should show you what the type is all about. Often you don't even have to leave your open tab, but you can if you want to! Just click the popup's header to explore the full file.&lt;/p&gt;

&lt;p&gt;Don't be afraid of type definition files. They're there for the linter, but they're also there for you, if you'll grant them your attention.&lt;/p&gt;

&lt;p&gt;Another trick: say you're using a 3rd party library function, and it takes in a complicated parameters object. Well, you can often simply import the parameter object's type, define your variable to be the same type, and get friendly warnings until you fill out every missing property. (And if the arguments' types are not exported, you can always use the built-in &lt;code&gt;Parameters&lt;/code&gt; type to get them yourself).&lt;/p&gt;

&lt;div class="highlight js-code-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;doSomething&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="s1"&gt;cool-library&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// These types are often exported, but if not, don't fear! `Parameters&amp;lt;&amp;gt;` can usually help you out&lt;/span&gt;
&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;DoSomethingArgs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Parameters&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="nx"&gt;doSomething&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="c1"&gt;// &amp;lt;-- an array;&lt;/span&gt;

&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;FirstArg&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;DoSomethingArgs&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="c1"&gt;// &amp;lt;-- the first argument;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;FirstArg&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;complicatedKey&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;complicatedValue&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="c1"&gt;// &amp;lt;-- now this object will have autocomplete, and red warning squiggles :)&lt;/span&gt;

&lt;span class="nf"&gt;doSomething&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;This tip works even better when you couple it with the auto-complete trick from tip #1, and the auto-import trick from tip #6.&lt;/p&gt;




&lt;h3&gt;
  
  
  5. If you have a list of options, try writing your own type instead of using a generic &lt;code&gt;string&lt;/code&gt; or &lt;code&gt;number&lt;/code&gt; type
&lt;/h3&gt;

&lt;p&gt;Let's say your passing in some names to your function:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;

&lt;span class="c1"&gt;// okay&lt;/span&gt;
&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;Props&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;name&lt;/span&gt;&lt;span class="p"&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;This will work. But what if you know that your name should be one of three, and nothing else? Perhaps you want your TypeScript error to warn you if you pass in and unacceptable name.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;

&lt;span class="c1"&gt;// better&lt;/span&gt;
&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;StarterPokemon&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Bulbasaur&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Charmander&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Squirtle&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;Props&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;StarterPokemon&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;This way, the &lt;code&gt;name&lt;/code&gt; prop can only be one of the three strings specified in the &lt;code&gt;StarterPokemon&lt;/code&gt; type.&lt;/p&gt;

&lt;p&gt;Writing your own stricter types is useful because you might forget later which options you have available, or another developer might take over the project and not know which Pokémon are available as starters and break the rule somewhere. Having a strict list of options prevents such a thing from occurring:&lt;/p&gt;

&lt;div class="highlight js-code-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;chooseStarterPokemon&lt;/span&gt; &lt;span class="o"&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="nx"&gt;StarterPokemon&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="nf"&gt;setPokemon&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="nf"&gt;chooseStarterPokemon&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Pikachu&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// error!&lt;/span&gt;
&lt;span class="c1"&gt;// Type '"Pikachu"' is not assignable to type 'StarterPokemon'.&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;Another bonus is that you will later be able to mouse over the &lt;code&gt;StarterPokemon&lt;/code&gt; type wherever you use it to get a reminder of what were the options. You can even add comments:&lt;/p&gt;

&lt;div class="highlight js-code-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;StarterPokemon&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Bulbasaur&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="c1"&gt;// grass&lt;/span&gt;
    &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Charmander&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="c1"&gt;// fire&lt;/span&gt;
    &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Squirtle&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="c1"&gt;// water&lt;/span&gt;
&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="cm"&gt;/** 
* Make sure to add that finaly semi-colon,
* or else the mouse-over info will stop after
* 'Squirtle' and won't show the final comment
*/&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;As a general tip, you might find it helpful to try to write your types so that you could later autocomplete your way through the whole project by using the &lt;code&gt;control + space&lt;/code&gt; tip from #1. To borrow from Einstein, try to make your types as restrictive as possible, but no more so than needed.&lt;/p&gt;




&lt;h3&gt;
  
  
  6. Auto-import all missing variables with &lt;code&gt;Cmd + .&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Many VS Code users know that you can auto-import individual things by just typing out the first few characters and then selecting the first VS Code dropdown suggestion. But you can also import all missing variables that are already declared in the file.&lt;/p&gt;

&lt;p&gt;If you're using TypeScript, all you have to do is click on an undefined variable/function/type and press &lt;code&gt;Cmd + .&lt;/code&gt;. VS Code should be able to suggest to you some options for where to import it from. If you've got several undefined items, it should even offer to 'Add all missing imports'.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpxq9s0fq33wb3izpzi6n.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpxq9s0fq33wb3izpzi6n.gif" alt="Image description"&gt;&lt;/a&gt;Why import stuff manually when VS code can do it all in one click?&lt;/p&gt;

&lt;p&gt;This trick works for both 3rd party libraries and your own code, as long as everything is exported correctly and written in TypeScript. And it nearly always works exactly as expected.&lt;/p&gt;

&lt;p&gt;In fact, most of the time I don't even check that the imports came from the right place after doing this. Also, you usually learn pretty quickly which things VS Code tends to import from the wrong places. For example, for me it often imports the Lodash 'get' function from the wrong library, so that is one of the few things I import manually.&lt;/p&gt;




&lt;h3&gt;
  
  
  7. Get optional props the smart way using a &lt;code&gt;?&lt;/code&gt; operator ("Optional chaining")
&lt;/h3&gt;

&lt;p&gt;Have you ever had to do this?&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;

&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;Item&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;prop&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;subprop&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="kr"&gt;string&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="kd"&gt;const&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;item&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;prop&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;prop&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;subprop&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;default&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;Seeing several &lt;code&gt;&amp;amp;&amp;amp;&lt;/code&gt; like that makes the code hard to understand at first glance. Wouldn't it be nice if you could tell TypeScript to get that deeply nested value, only if &lt;code&gt;item&lt;/code&gt; and &lt;code&gt;prop&lt;/code&gt; actually exist as well?&lt;/p&gt;

&lt;p&gt;Well, it turns out there is! Try this:&lt;/p&gt;

&lt;div class="highlight js-code-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;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;prop&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;subprop&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;default&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 &lt;code&gt;?&lt;/code&gt; operator is a sneaky way to tell TypeScript (and newer versions of JavaScript) to only go deeper if the higher-up key exists. In other words, only look for &lt;code&gt;prop&lt;/code&gt; if &lt;code&gt;item&lt;/code&gt; is defined and an is object, and only look for &lt;code&gt;subprop&lt;/code&gt; if &lt;code&gt;prop&lt;/code&gt; is defined and is an object.&lt;/p&gt;

&lt;p&gt;The official name for this syntax is "optional chaining". It's easy and intuitive, and it'll probably save you a few lines of code.&lt;/p&gt;




&lt;h3&gt;
  
  
  8. Work with old JS files by enabling &lt;code&gt;allowJs&lt;/code&gt; in &lt;code&gt;tsconfig.json&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;This is a quick and easy tip that might not be obvious for the beginners out there.&lt;/p&gt;

&lt;p&gt;You can easily mix TypeScript and plain old JavaScript files. All you have to do is make a little edit in your &lt;code&gt;tsconfig.json&lt;/code&gt; file:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"compilerOptions"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"allowJs"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;...&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;other&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;options&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;


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

&lt;/div&gt;

&lt;p&gt;Now your TS compiler won't block your development. But you'll probably have to use a lot of &lt;code&gt;any&lt;/code&gt; types for any JS files you import.&lt;/p&gt;




&lt;h3&gt;
  
  
  9. Automatically refactor your typed objects into a named interface
&lt;/h3&gt;

&lt;p&gt;Let's say you have a function that takes in a long object:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;

&lt;span class="nx"&gt;renderFAQItem&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;faqQuestion&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;faqAnswer&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="kr"&gt;string&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="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="c1"&gt;// component&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;The &lt;code&gt;{ faqQuestion?: string, faqAnswer?: string }&lt;/code&gt; definition makes this line of code too long. Worse, it also makes your code a bit less maintainable.&lt;/p&gt;

&lt;p&gt;Thankfully VS Code lets you turn it into a named interface at the click of a button:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgqfsi0ascqbburpyzot8.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgqfsi0ascqbburpyzot8.gif" alt="Image description"&gt;&lt;/a&gt;In one click, VS code can make a named interface for you at the top of the file.&lt;/p&gt;

&lt;p&gt;That light bulb is actually quite handy, if you know how to use it. It can also refactor variables into constants, lines into functions, generate get/set methods for classes, and more. There's a whole &lt;a href="https://code.visualstudio.com/docs/languages/typescript" rel="noopener noreferrer"&gt;section on refactoring&lt;/a&gt; in the VS Code TypeScript documentation.&lt;/p&gt;




&lt;h3&gt;
  
  
  10. Combine TypeScript with JSDoc for awesome documentation right in your VS Code.
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://jsdoc.app" rel="noopener noreferrer"&gt;JSDoc&lt;/a&gt; is a pretty awesome skill to have for any JavaScript project. And fortunately it can be combined with type definitions as well.&lt;/p&gt;

&lt;p&gt;VS Code automatically recognizes JSDoc comments when you use a multiline comment that starts with two asterisks: &lt;code&gt;/** Insert content here */&lt;/code&gt;. You can also add some keywords (marked by @-symbols) for even more intellisense. And the great thing about JSDoc comments is that, unlike regular &lt;code&gt;//&lt;/code&gt; comments, the things you write down will be visible on-hover, anywhere in your project!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ff3isd46ygp29r7uxswz6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ff3isd46ygp29r7uxswz6.png" alt="Image description"&gt;&lt;/a&gt;Add JSDoc comments to your interface properties, and you will be able to see a description for that property when hovering over it. This will work even if you use this component in another file!&lt;/p&gt;

&lt;p&gt;This is a great addition to your codebase when working in teams, when you want to give other developers a clearer explanation of what your code is supposed to do, and how it's supposed to be used.&lt;/p&gt;

&lt;p&gt;Many of the best libraries, such as &lt;a href="https://mui.com" rel="noopener noreferrer"&gt;Material UI&lt;/a&gt;, annotate their TS definitions with JSDoc comments, so you could see the documentation for that property right in your VSCode tab, without opening any links. Often they even include the links anyway, in case you're hungry for more info :)&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4j8ax716kuwe79w8rrew.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4j8ax716kuwe79w8rrew.png" alt="Image description"&gt;&lt;/a&gt;Many of the best libraries heavily annotate their types with JSDoc comments, and often include links to more complete documentation.&lt;/p&gt;




&lt;p&gt;These are the main things I wish I knew when starting out with TypeScript.&lt;/p&gt;

&lt;p&gt;Keep in mind that TypeScript was created to help you, not to annoy you. As a rule of thumb, I try to write my TS in such a way so that I would later be able to autocomplete my code as much as possible.&lt;/p&gt;

&lt;p&gt;I hope these tips could be helpful for you. Good luck, and have fun!&lt;/p&gt;

</description>
      <category>typescript</category>
      <category>vscode</category>
      <category>tricks</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Creating side effects with the onChange callback in Redux Form (TypeScript included!)</title>
      <dc:creator>Deckstar</dc:creator>
      <pubDate>Fri, 16 Oct 2020 19:44:42 +0000</pubDate>
      <link>https://forem.com/deckstar/creating-side-effects-with-the-onchange-callback-in-redux-form-typescript-included-3np6</link>
      <guid>https://forem.com/deckstar/creating-side-effects-with-the-onchange-callback-in-redux-form-typescript-included-3np6</guid>
      <description>&lt;p&gt;Redux Form is a common way to handle forms in React. But as with any large, complicated library, there are always a couple of features that may not seem obvious at first. In this article, we will take a look at how to use the onChange callback in the &lt;code&gt;reduxForm({})&lt;/code&gt; config.&lt;/p&gt;

&lt;h2&gt;
  
  
  The use case
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;This function is useful when you want to introduce some side effects to your forms.&lt;/strong&gt; This side effect could be anything: maybe you want to fetch data for a dropdown. Or maybe you just want some values to change automatically.&lt;/p&gt;

&lt;p&gt;In my case, I was developing a form for granting participation credits to students for showing up to experiments. Say you’re a professor: a student shows up to your experiment, so you mark him as “participated” and grant him, for example, 5 credits for his performance.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F1gi033gioitf48xgy3pl.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F1gi033gioitf48xgy3pl.png" alt="Student participated"&gt;&lt;/a&gt;A simple credit granting form. You’re a professor running an experiment, and your university’s budget department demands that you submit a form for each student saying how they participated, and how many credits they should get.&lt;/p&gt;

&lt;p&gt;Here’s where the &lt;code&gt;onChange&lt;/code&gt; comes in: another student didn’t show up, with neither an excuse nor a warning. So you mark him as a “no-show”. If a student is a no-show, you probably want him to get zero credits, right? &lt;/p&gt;

&lt;p&gt;Now, wouldn’t it be nice if your Redux Form automatically chose zero credits for the student if you deemed them a “no-show”? That certainly sounds like better UX to me. But beyond UX, you may very well need such functionality in a case like this, where granting credit to a non-participant doesn’t make any sense, and probably breaks the rules of your university’s budget allocation.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fm52xa9z0fya0gud1jkmq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fm52xa9z0fya0gud1jkmq.png" alt="Student no-show"&gt;&lt;/a&gt;Wouldn’t it be nice if selecting the big red X category automatically set the credits to zero?&lt;/p&gt;

&lt;p&gt;Of course, you could just add some logic in your component, or in your Redux action, or in your backend. But it’s probably more convenient to have a simple solution that immediately solves the need for visual logic, Redux state logic, and the eventual form submission logic as well.&lt;/p&gt;

&lt;p&gt;Enter the &lt;code&gt;onChange&lt;/code&gt; callback: a simple solution to immediately handle the change according to your rules, leaving the rest of your component, reducers and backend none the wiser that a participant could’ve theoretically been in the big red X category and still gotten some points.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to implement
&lt;/h2&gt;

&lt;p&gt;Let’s say our form component looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Component&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="s1"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&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;reduxForm&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="s1"&gt;redux-form&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="c1"&gt;// etc. sub-component imports&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ParticipantModal&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;Component&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;render&lt;/span&gt;&lt;span class="p"&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="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Container&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Header&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;ScrollView&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;CreditStatusButtons&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
          &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;CreditCount&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;ScrollView&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;SaveButton&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Container&lt;/span&gt;&lt;span class="p"&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ParticipantForm&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;reduxForm&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;form&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;participantForm&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;ParticipantModal&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;ParticipantForm&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We start out with a simple modal with some sub components (the code for which is not important for this illustration). The way Redux Form works is that our &lt;code&gt;ParticipantModal&lt;/code&gt; component automatically gets access to an auto-generated object called “form”, which lives in our Redux state and includes pretty much everything needed to make a nice, reactive form. Redux Form takes care of most things, but for our “set credits to zero automatically” we will need to write a little custom logic.&lt;/p&gt;

&lt;p&gt;We start out by writing out what we actually want to happen and when. So we write a &lt;code&gt;handleOnFormChange&lt;/code&gt; function. Let’s say that we have two variables in this form: the &lt;code&gt;studentStatus&lt;/code&gt; (participated, excused, no-show, etc.) and the &lt;code&gt;creditValue&lt;/code&gt; (the number of credits to grant).&lt;/p&gt;

&lt;p&gt;We can &lt;strong&gt;start out by adding an “onChange” field into our reduxForm&lt;/strong&gt; config on the bottom. Then we &lt;strong&gt;declare a function that we want to be called when a form value (any value) changes&lt;/strong&gt;. The config will automatically pass in four variables into this function, all of which we will need: &lt;code&gt;newValues&lt;/code&gt;, &lt;code&gt;dispatch&lt;/code&gt;, &lt;code&gt;props&lt;/code&gt; and &lt;code&gt;previousValues&lt;/code&gt; (in that order!).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;handleOnFormChange&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;newValues&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;props&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;previousValues&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="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;studentStatus&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;newStudentStatus&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;newValues&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;studentStatus&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;prevStudentStatus&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;creditValue&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;prevCreditValue&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;previousValues&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;change&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;changeField&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="cm"&gt;/*
    if the user sets the participant as a "no show",
    then their credit value should be automatically set to zero
  */&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nx"&gt;newStudentStatus&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="nx"&gt;prevStudentStatus&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="c1"&gt;// to prevent dispatching every time&lt;/span&gt;
    &lt;span class="nx"&gt;newStudentStatus&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;noShow&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;
    &lt;span class="nx"&gt;prevCreditValue&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
  &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;dispatch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;changeField&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;creditValue&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ParticipantForm&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;reduxForm&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;form&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;participantForm&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;onChange&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;handleOnFormChange&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// &amp;lt;-- add this&lt;/span&gt;
&lt;span class="p"&gt;})(&lt;/span&gt;&lt;span class="nx"&gt;ParticipantModal&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;newValues&lt;/code&gt; and &lt;code&gt;previousValues&lt;/code&gt; are self-explanatory: they are the form values that were stored in the Redux state before and after the user changed something. &lt;code&gt;Dispatch&lt;/code&gt; is the Redux dispatch function that is used with every Redux action &amp;amp; reducer. And &lt;code&gt;props&lt;/code&gt; are the properties that reduxForm passes into your component, from which we destructure the &lt;code&gt;change&lt;/code&gt; function. (I also rename it to &lt;code&gt;changeField&lt;/code&gt;, to make it more obvious.) This function takes in the name of the value that we want to change (in our case, the &lt;code&gt;creditValue&lt;/code&gt;), and the new value we want to set (zero). Make sure to check previous values so the dispatch is called only when you change the status!&lt;/p&gt;

&lt;p&gt;And just like that, we’re done! With this little bit of logic, we have achieved the functionality that we wanted.&lt;/p&gt;

&lt;h2&gt;
  
  
  Adding TypeScript
&lt;/h2&gt;

&lt;p&gt;This particular project required TypeScript. Though lately I’ve been becoming more and more of a TypeScript fan, one thing I never liked was spending a lot of time looking for interfaces / types for 3rd party libraries.&lt;/p&gt;

&lt;p&gt;Well I’ve got you covered. Simply &lt;strong&gt;copy paste the type imports &amp;amp; uses below&lt;/strong&gt;, and your linter should get rid of quite a few red lines. You’re going to need &lt;code&gt;Dispatch&lt;/code&gt; from ‘react’ and &lt;code&gt;DecoratedFormProps&lt;/code&gt; from ‘redux-form’.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Component&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="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&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;reduxForm&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;DecoratedFormProps&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="s1"&gt;redux-form&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;You’ll also need to declare your own interface for the values in your form.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;YourForm&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;studentStatus&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;creditValue&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="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Add them to your “handleOnFormChange” function.&lt;/p&gt;

&lt;p&gt;With that, &lt;strong&gt;our final result&lt;/strong&gt; should look something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Component&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="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&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;reduxForm&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;DecoratedFormProps&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="s1"&gt;redux-form&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="c1"&gt;// etc. other component imports&lt;/span&gt;

&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;YourForm&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;studentStatus&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;creditValue&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="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ParticipantModal&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;Component&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;render&lt;/span&gt;&lt;span class="p"&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="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Container&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Header&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;ScrollView&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;CreditStatusButtons&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
          &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;CreditCount&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;ScrollView&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;SaveButton&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Container&lt;/span&gt;&lt;span class="p"&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;handleOnFormChange&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nx"&gt;newValues&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;YourForm&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="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="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;DecoratedFormProps&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;YourForm&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{},&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="nx"&gt;previousValues&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;YourForm&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="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;studentStatus&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;newStudentStatus&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;newValues&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;studentStatus&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;prevStudentStatus&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;creditValue&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;prevCreditValue&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;previousValues&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;change&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;changeField&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="cm"&gt;/*
    if the user sets the participant as a "no show",
    then their credit value should be automatically set to zero
  */&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nx"&gt;newStudentStatus&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="nx"&gt;prevStudentStatus&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="c1"&gt;// to prevent dispatching every time&lt;/span&gt;
    &lt;span class="nx"&gt;newStudentStatus&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;noShow&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;
    &lt;span class="nx"&gt;prevCreditValue&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
  &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;dispatch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;changeField&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;creditValue&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ParticipantForm&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;reduxForm&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;form&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;participantForm&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;onChange&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;handleOnFormChange&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;})(&lt;/span&gt;&lt;span class="nx"&gt;ParticipantModal&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;ParticipantForm&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 it! 🙂&lt;/p&gt;

&lt;h2&gt;
  
  
  P.S.: “But I’m still getting a TypeScript linter error?”
&lt;/h2&gt;

&lt;p&gt;At the end of this, you may see a linter error at the bottom. Specifically, the &lt;code&gt;ParticipantModal&lt;/code&gt; component that gets passed into reduxForm will have a warning that says something like &lt;code&gt;Argument of type 'typeof ParticipantModal' is not assignable to parameter of type 'ComponentType&amp;lt;InjectedFormProps&amp;lt;FormValues, {}, string&amp;gt;&amp;gt;'&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;I’ll be honest, I have no idea how to fix this linter error. I’ve tried and I’ve Googled it a dozen times, to no avail. I’ve just accepted that all my Redux Form components will have one TypeScript error on the bottom.&lt;/p&gt;

&lt;p&gt;If you find a solution, would you please kindly share it with me? As a token of my gratitude, I promise I’ll send you the best picture of a cookie I can find 😇&lt;/p&gt;

&lt;p&gt;Thanks for reading!&lt;/p&gt;

&lt;h2&gt;
  
  
  Edit on 2 December 2020: TypeScript linter error solved
&lt;/h2&gt;

&lt;p&gt;Here's how to solve that TypeScript error above. Change the following lines as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// import { reduxForm, DecoratedFormProps } from 'redux-form'; // old&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;reduxForm&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;DecoratedFormProps&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;InjectedFormProps&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="s1"&gt;redux-form&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// ...&lt;/span&gt;

&lt;span class="c1"&gt;// class ParticipantModal extends Component { // old&lt;/span&gt;
&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ParticipantModal&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;Component&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Props&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;InjectedFormValues&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;YourForm&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Props&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="c1"&gt;// Props is the interface with the normal, non-form-related props of this component &lt;/span&gt;

&lt;span class="c1"&gt;// ...&lt;/span&gt;

  &lt;span class="c1"&gt;// props: DecoratedFormProps&amp;lt;YourForm, {}, string&amp;gt;, // old&lt;/span&gt;
  &lt;span class="na"&gt;props&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;DecoratedFormProps&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;YourForm&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Props&lt;/span&gt;&lt;span class="p"&gt;,&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="c1"&gt;// ...&lt;/span&gt;

&lt;span class="c1"&gt;// const ParticipantForm = reduxForm({ // old&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ParticipantForm&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;reduxForm&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;YourForm&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Props&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;Other lines shouldn't need any changes.&lt;/p&gt;

&lt;p&gt;If your component has no Props, you can replace the "Props" interface with an empty object, e.g. &lt;code&gt;class ParticipantModal extends Component&amp;lt;{}, InjectedFormValues&amp;lt;YourForm, {}&amp;gt;&amp;gt;&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Thanks again for reading, and good luck with your forms!&lt;/p&gt;

</description>
      <category>reduxform</category>
      <category>typescript</category>
      <category>react</category>
      <category>redux</category>
    </item>
  </channel>
</rss>
