<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: David Johnston</title>
    <description>The latest articles on DEV Community by David Johnston (@dwjohnston).</description>
    <link>https://dev.to/dwjohnston</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%2F186272%2Ff47eedbb-8aa2-47b9-8e53-7c18ecbe6445.jpeg</url>
      <title>DEV Community: David Johnston</title>
      <link>https://dev.to/dwjohnston</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/dwjohnston"/>
    <language>en</language>
    <item>
      <title>What are your favourite emoji to use in build pipelines?</title>
      <dc:creator>David Johnston</dc:creator>
      <pubDate>Fri, 30 Sep 2022 00:00:08 +0000</pubDate>
      <link>https://dev.to/dwjohnston/what-are-your-favourite-emoji-to-use-in-build-pipelines-470p</link>
      <guid>https://dev.to/dwjohnston/what-are-your-favourite-emoji-to-use-in-build-pipelines-470p</guid>
      <description>&lt;p&gt;I absolutely love using emojis in things like build pipelines or documentation.  I find a list like this: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Run Tests&lt;/li&gt;
&lt;li&gt;Lint&lt;/li&gt;
&lt;li&gt;Build artefact &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Is a whole lot easy to read when it has emojis:  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;🧪 Run tests &lt;/li&gt;
&lt;li&gt;🔎 Lint&lt;/li&gt;
&lt;li&gt;🏗 Build artefact &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The emojis give very quick identifiable reference points - in what otherwise might look like a wall of text. &lt;/p&gt;

&lt;p&gt;So what are your favourite emojis to use for common terms? &lt;/p&gt;

&lt;p&gt;Here's some of mine: &lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Emoji&lt;/th&gt;
&lt;th&gt;Meaning&lt;/th&gt;
&lt;th&gt;Notes&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;🧪 👩🏾‍🔬&lt;/td&gt;
&lt;td&gt;Test&lt;/td&gt;
&lt;td&gt;It can be good to have different emojis for different test types&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;👷 🏗&lt;/td&gt;
&lt;td&gt;Build&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;⚙️ 🔧&lt;/td&gt;
&lt;td&gt;Configure&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;📦&lt;/td&gt;
&lt;td&gt;Artefact&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;🔎 🕵️‍♀️&lt;/td&gt;
&lt;td&gt;Inspect/Lint&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;👮🏼&lt;/td&gt;
&lt;td&gt;Type Check&lt;/td&gt;
&lt;td&gt;Or any other strict/grumpy check&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;👩‍🦯&lt;/td&gt;
&lt;td&gt;Lint&lt;/td&gt;
&lt;td&gt;'Lets check for things that might trip us up'&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;👨‍🎤&lt;/td&gt;
&lt;td&gt;Formatting&lt;/td&gt;
&lt;td&gt;'They're an artist'&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;🛃&lt;/td&gt;
&lt;td&gt;Security check on dependencies&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;👩🏼‍🌾&lt;/td&gt;
&lt;td&gt;User&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;🧙&lt;/td&gt;
&lt;td&gt;Admin&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;🧛‍♂️&lt;/td&gt;
&lt;td&gt;Manager&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

</description>
      <category>ci</category>
      <category>emoji</category>
    </item>
    <item>
      <title>What do you think about providing Cypress and RTL selector and assertion functions alongside your components?</title>
      <dc:creator>David Johnston</dc:creator>
      <pubDate>Tue, 06 Sep 2022 07:05:39 +0000</pubDate>
      <link>https://dev.to/dwjohnston/what-do-you-think-about-providing-cypress-and-rtl-selector-and-assertion-functions-alongside-your-components-3h16</link>
      <guid>https://dev.to/dwjohnston/what-do-you-think-about-providing-cypress-and-rtl-selector-and-assertion-functions-alongside-your-components-3h16</guid>
      <description>&lt;p&gt;Here's an idea I've just started toying with. &lt;/p&gt;

&lt;p&gt;So in my project the folder structure for any given component looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/MyComponent
   MyComponent.tsx - The actual component
   MyComponent.stories.tsx - Storybook stories
   MyComponent.test.tsx - RTL tests. 

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

&lt;/div&gt;



&lt;p&gt;Fairly straight forward. &lt;/p&gt;

&lt;p&gt;Something I've been running into recently, particularly with writing Cypress tests, is that often writing either interactions with my components (eg. click the button, select an item from the autocomplete) or assertions on them (eg. the multiselect contains value 'foo') has quite a lot friction. I'm often going into the RTL test and seeing what I've done there, and copying an modifying it. &lt;/p&gt;

&lt;p&gt;Now I know that Testing Libraries whole philosophy is 'write tests in the way that a user would interact with the application' - but it's often not that straightforward, or it's a bit tedious. &lt;/p&gt;

&lt;p&gt;So what I've considered is two more files along side the others;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;MyComponent.rtl-selectors.ts
MyComponent.cypress-selectors.ts
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These would contains functions like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function selectItemInMultiSelect(label: string, itemName: string) //...

function assertMultiSelectContainsItem(label: string, itemName; string) //... 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And the idea is, you could import these functions in your RTL/Cypress tests to assist with interactions. &lt;/p&gt;

&lt;p&gt;Has anyone tried such a thing, and how did it go?&lt;/p&gt;

</description>
      <category>react</category>
      <category>cypress</category>
      <category>testing</category>
    </item>
    <item>
      <title>Cross posting from your blog to Dev.to. A good idea?</title>
      <dc:creator>David Johnston</dc:creator>
      <pubDate>Sun, 11 Oct 2020 09:12:25 +0000</pubDate>
      <link>https://dev.to/dwjohnston/cross-posting-from-your-blog-to-dev-to-a-good-idea-aja</link>
      <guid>https://dev.to/dwjohnston/cross-posting-from-your-blog-to-dev-to-a-good-idea-aja</guid>
      <description>&lt;p&gt;Been in a bit of a creative rut recently, and I'm figuring that the best thing to do, the thing I'm most inclined to do, is make blog posts about anything and everything. &lt;/p&gt;

&lt;p&gt;I definitely want to do this as part of my own blog where I fully control the content. I've learned a lesson (nicely articulated by &lt;a href="https://austinkleon.com/"&gt;Austin Kleon&lt;/a&gt; in his book &lt;em&gt;Show Your Work&lt;/em&gt;) when I ran a '&lt;a href="https://www.facebook.com/HumansOfWelly/"&gt;Humans of&lt;/a&gt;' page that was a Facebook page only. It now kinda sucks that all of that content is just on Facebook and I've since lost the original photos, the accompanying text only there etc. I wish I'd set up a blog like the original Humans of New York did. &lt;/p&gt;

&lt;p&gt;So the question is - should I cross-publish all of my blog posts to Dev.to and Medium as well? &lt;/p&gt;

&lt;p&gt;Is this a common practice? I've had a quick scroll through my Dev.to feed and I can't see many people back-linking to their blog. &lt;/p&gt;

&lt;p&gt;As I see it: &lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Pros&lt;/th&gt;
&lt;th&gt;Cons&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;More exposure&lt;/td&gt;
&lt;td&gt;A bit of work setting it up programatically&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Native conversation/reply functionality within the third party mediums&lt;/td&gt;
&lt;td&gt;Back links on the posts look spammy&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;Possible adverse SEO affects for the blog?&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;What say you?&lt;/p&gt;

</description>
      <category>meta</category>
      <category>blogging</category>
    </item>
    <item>
      <title>Type widening on strings</title>
      <dc:creator>David Johnston</dc:creator>
      <pubDate>Tue, 29 Sep 2020 03:23:06 +0000</pubDate>
      <link>https://dev.to/dwjohnston/type-widening-on-strings-4i99</link>
      <guid>https://dev.to/dwjohnston/type-widening-on-strings-4i99</guid>
      <description>&lt;h1&gt;
  
  
  The Problem
&lt;/h1&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;Roles&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;student&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="s2"&gt;teacher&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; 

&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;Person&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;role&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Roles&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="nl"&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="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;doSomethingWithPerson&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;person&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Person&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;person&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;andy&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;role&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;teacher&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
    &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;andy&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
    &lt;span class="na"&gt;age&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;31&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="nx"&gt;doSomethingWithPerson&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;andy&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;//Argument of type '{ role: string; name: string; age: number; }' is not assignable to parameter of type 'Person'.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;&lt;a href="https://www.typescriptlang.org/play?#code/C4TwDgpgBASg9gGwgZygXigImcArgEwgDthMoAfLYCAQwGMALCAJ0wG4oAoT0SKABRbI4RdFADenKNKjNEEAFyx5yDlJlEaAW0VQczAJZEA5mplQax3UVxaARizUBfbgDNcROsAMio+OADKcDrADEbGAOoGoYLMwkQAFJBxIkqx8QCUEurSdCLCSAB0CHDGSUIiGc7ceUQ4FkT4IGKS5nJISpjU9EysADRc5po6nTSNIJgDORZWSgDMAIycTmzc-kEhYSZRMRWJY01VQA"&gt;Playground Link&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This code produces the error:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Argument of type '{ role: string; name: string; age: number; }' is not assignable to parameter of type 'Person'.
  Types of property 'role' are incompatible.
    Type 'string' is not assignable to type 'Roles'.
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;What's going on here? &lt;/p&gt;

&lt;p&gt;The &lt;code&gt;andy&lt;/code&gt; object we declare does match the type &lt;code&gt;Person&lt;/code&gt; that the function wants, so why is TypeScript complaining? &lt;/p&gt;

&lt;h1&gt;
  
  
  Quick Solution
&lt;/h1&gt;

&lt;p&gt;Declare the string &lt;code&gt;"teacher"&lt;/code&gt; &lt;code&gt;as const&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;andy&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;role&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;teacher&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="k"&gt;as&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;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;andy&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
    &lt;span class="na"&gt;age&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;31&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="nx"&gt;doSomethingWithPerson&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;andy&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h1&gt;
  
  
  Explanation
&lt;/h1&gt;

&lt;p&gt;In this scenario when we declare the object &lt;code&gt;andy&lt;/code&gt; TypeScript &lt;em&gt;infers&lt;/em&gt; the type of the &lt;code&gt;role&lt;/code&gt; property as &lt;code&gt;string&lt;/code&gt;, any string!&lt;/p&gt;

&lt;p&gt;While &lt;code&gt;"teacher"&lt;/code&gt; and &lt;code&gt;"student"&lt;/code&gt; are strings, they are a &lt;em&gt;subset&lt;/em&gt; of strings. &lt;/p&gt;

&lt;p&gt;The &lt;code&gt;Person&lt;/code&gt; type doesn't want &lt;em&gt;any&lt;/em&gt; string, it wants just those two particular strings. &lt;/p&gt;

&lt;p&gt;That TypeScript infers the type as &lt;code&gt;string&lt;/code&gt; and not as &lt;code&gt;"teacher"&lt;/code&gt; is called &lt;a href="https://github.com/microsoft/TypeScript-New-Handbook/blob/master/reference/Widening-and-Narrowing.md"&gt;type widening&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;What TypeScript is doing, is allowing for that you might later write some code like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   andy.role = "foobar"; 
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;(That is, you're &lt;em&gt;mutating&lt;/em&gt; the &lt;code&gt;andy&lt;/code&gt; object). &lt;/p&gt;

&lt;p&gt;What the &lt;code&gt;as const&lt;/code&gt; keyword does is just prevent the type widening. &lt;a href="https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-4.html#const-assertions"&gt;See the documentation here&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;What you're also doing is telling TypeScript 'don't worry, I promise I'm not going to reassign this property', and if you try, TypeScript will give you an error:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;andy&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;role&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;teacher&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="k"&gt;as&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;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;andy&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
    &lt;span class="na"&gt;age&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;31&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="nx"&gt;andy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;role&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;foobar&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;//Type '"foobar"' is not assignable to type '"teacher"'.(2322) &lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h1&gt;
  
  
  Alternative solutions
&lt;/h1&gt;

&lt;p&gt;Declare the string &lt;code&gt;"teacher"&lt;/code&gt; &lt;code&gt;as "teacher"&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;andy&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;role&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;teacher&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;teacher&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
    &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;andy&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
    &lt;span class="na"&gt;age&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;31&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="nx"&gt;doSomethingWithPerson&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;andy&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;What this does is instead of using the &lt;code&gt;as const&lt;/code&gt; keyword to prevent type widening, it just explicitly sets the type of the &lt;code&gt;role&lt;/code&gt; property to &lt;code&gt;"teacher"&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;Both &lt;code&gt;as const&lt;/code&gt; and &lt;code&gt;as "teacher"&lt;/code&gt; have the same end effect, the &lt;code&gt;role&lt;/code&gt; property's type is &lt;code&gt;"teacher"&lt;/code&gt;. &lt;/p&gt;

</description>
      <category>typescript</category>
    </item>
    <item>
      <title>Type inference from React.useState</title>
      <dc:creator>David Johnston</dc:creator>
      <pubDate>Tue, 29 Sep 2020 02:59:19 +0000</pubDate>
      <link>https://dev.to/dwjohnston/react-usestate-argument-of-type-string-is-not-assignable-to-parameter-of-type-setstateaction-undefined-27po</link>
      <guid>https://dev.to/dwjohnston/react-usestate-argument-of-type-string-is-not-assignable-to-parameter-of-type-setstateaction-undefined-27po</guid>
      <description>&lt;h1&gt;
  
  
  The Problem
&lt;/h1&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="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="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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Foo&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="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setValue&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;useState&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;input&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="nx"&gt;onChange&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{(&lt;/span&gt;&lt;span class="nx"&gt;e&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;setValue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;&lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&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;&lt;a href="https://www.typescriptlang.org/play?#code/JYWwDg9gTgLgBAJQKYEMDG8BmUIjgIilQ3wG4AoctCAOwGd4AxCCOAXjgAoBKdgPjgBvcnFFxq9eAG0AbigA2AVyQAaOHSQwAaguUBddomIwAdIo0BlGChhIepOCLFEYiqDTgAeYDTCL4ckpIhoKBygC+cLQAwgAWKDQA5sEcgpxIvGwCGtq6dkgm1lDJpmEZ4QD0fOThQA"&gt;Playground Link&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This code produces the following TypeScript error:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nx"&gt;Argument&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;string&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="k"&gt;is&lt;/span&gt; &lt;span class="nx"&gt;not&lt;/span&gt; &lt;span class="nx"&gt;assignable&lt;/span&gt; &lt;span class="nx"&gt;to&lt;/span&gt; &lt;span class="nx"&gt;parameter&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;SetStateAction&amp;lt;undefined&amp;gt;&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;.(&lt;/span&gt;&lt;span class="mi"&gt;2345&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h1&gt;
  
  
  Quick Solution
&lt;/h1&gt;

&lt;p&gt;Explicitly state the generic type:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="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="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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Foo&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="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setValue&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;useState&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;|&lt;/span&gt; &lt;span class="kc"&gt;undefined&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="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;input&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="nx"&gt;onChange&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{(&lt;/span&gt;&lt;span class="nx"&gt;e&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;setValue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;&lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&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;Or set the initial state to an empty string.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="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="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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Foo&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="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setValue&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;''&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;input&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="nx"&gt;onChange&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{(&lt;/span&gt;&lt;span class="nx"&gt;e&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;setValue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;&lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&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;(This may not be appropriate for all cases, ie maybe you really do want to leave that value undefined). &lt;/p&gt;

&lt;h1&gt;
  
  
  Explanation
&lt;/h1&gt;

&lt;p&gt;The &lt;code&gt;useState&lt;/code&gt; function has a generic parameter which we are not setting/declaring in the original case. &lt;/p&gt;

&lt;p&gt;This leaves TypeScript to &lt;em&gt;infer&lt;/em&gt; the generic type from the arguments given. &lt;/p&gt;

&lt;p&gt;In this case &lt;code&gt;useState()&lt;/code&gt; with no arguments, TypeScript infers the type as &lt;code&gt;undefined&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;&lt;em&gt;TypeScript doesn't know that you later want to set a string into state here&lt;/em&gt;. &lt;/p&gt;

&lt;p&gt;That is, leaving the generic parameter off is equivalent of doing:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setValue&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;useState&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kc"&gt;undefined&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 generic parameter determines the type of the &lt;code&gt;value&lt;/code&gt; and &lt;code&gt;setValue&lt;/code&gt; variables. &lt;/p&gt;

&lt;p&gt;In this case, the &lt;code&gt;setValue&lt;/code&gt; function is going to be the equivalent of:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;setValue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;undefined&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;void&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;input&lt;/code&gt; component doesn't like this, the event is creating has a &lt;code&gt;target.value&lt;/code&gt; of type &lt;code&gt;string&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;So to solve this, we can either explicitly set the generic type, or be aware of when and how TypeScript is going to infer the generic type.  &lt;/p&gt;

</description>
      <category>typescript</category>
      <category>react</category>
    </item>
    <item>
      <title>Has VS Code got worse recently?</title>
      <dc:creator>David Johnston</dc:creator>
      <pubDate>Thu, 02 Jul 2020 05:30:03 +0000</pubDate>
      <link>https://dev.to/dwjohnston/has-vs-code-got-worse-recently-em3</link>
      <guid>https://dev.to/dwjohnston/has-vs-code-got-worse-recently-em3</guid>
      <description>&lt;p&gt;While screen sharing today, a colleague commented that it seems like VS Code has got less stable in recent weeks - and that does appear to be the case. &lt;/p&gt;

&lt;p&gt;Issues are mainly around: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Linting (Linter failing to fire and requiring a VSCode restart)&lt;/li&gt;
&lt;li&gt;Whatever you call it when you can mouse over something for information, or CTRL/CMD + click to follow through it. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Anyone else experiencing this? Or is there some kind of code decay that would cause this? &lt;/p&gt;

</description>
      <category>vscode</category>
      <category>ide</category>
    </item>
    <item>
      <title>What's the etiquette on posting to both Stack Overflow and dev.to?</title>
      <dc:creator>David Johnston</dc:creator>
      <pubDate>Wed, 08 Apr 2020 07:05:07 +0000</pubDate>
      <link>https://dev.to/dwjohnston/what-s-the-etiquette-on-posting-to-both-stack-overflow-and-dev-to-a6k</link>
      <guid>https://dev.to/dwjohnston/what-s-the-etiquette-on-posting-to-both-stack-overflow-and-dev-to-a6k</guid>
      <description>&lt;p&gt;I'm fairly new to dev.to. &lt;/p&gt;

&lt;p&gt;I love the features and UX of Stack Exchange, but have found it quite frustrating when asking questions about software architecture and design philosophies on softwareengineering.stackexchange.com not being well received. &lt;/p&gt;

&lt;p&gt;So where dev.to has looser 'what's on topic' requirements I'm figuring I can post here. &lt;/p&gt;

&lt;p&gt;Now the thing is - I've recently asked a &lt;a href="https://dev.to/dwjohnston/what-s-going-on-with-index-types-in-typescript-1dln"&gt;pretty technically specific question&lt;/a&gt; that would probably be well received on Stack Overflow -but is that considered bad form, either here or there? &lt;/p&gt;

</description>
      <category>etiquette</category>
    </item>
    <item>
      <title>What's going on with index types in TypeScript?</title>
      <dc:creator>David Johnston</dc:creator>
      <pubDate>Wed, 08 Apr 2020 06:51:02 +0000</pubDate>
      <link>https://dev.to/dwjohnston/what-s-going-on-with-index-types-in-typescript-1dln</link>
      <guid>https://dev.to/dwjohnston/what-s-going-on-with-index-types-in-typescript-1dln</guid>
      <description>&lt;p&gt;&lt;a href="https://www.typescriptlang.org/play/#code/FAFwngDgpgBAYgewTAvDA3sG2CGAuGAZxACcBLAOwHMBuLbAIwIoFcBbBqEu7GARmYsANkLoBfYKEiwAgqnhIA2gCIcygLo0YAem3Fy1GFOgwAQvMQIVDDVt2sOXY7ADyDAFYuKsNJcV9NHW1WES1JZxgAFQQAZVJKKgslZRBY+OpbIIAKAEpUAD4idKoIgDUcIRYoQiSrZQA3CqrCTN0ABRIEaBJwGAByRsrqvpgAEwRqmAoEEBgoAA8yYhgEChhwEz7LPoA6LIAmAGZDgE4c8I3YACUoADM3dygAYxBTMEjpADl2ThJaxQcv0Cug+m22MAAFjgatMYGwcCAnhCEjBKKMFkQyFQKAiWCRYLcEH9Lv1AVxdgcAKyHADs5xJN3uHmer3e0jiBkSviU+gSwO0oNgWyQIyhMOQ8MRyMMaIxhCxOJAeIJRPW0lJP3Je321Lp4UkJIAsmAZCQSDgwPJFLzqAAaKaakj2m1UTQG9UALS4yDQxtN5rAigADPyg0YSV4fDA-WaLf5+cpVlBlBd1TdRiwnlGYwGVPiM1nWtoGVAC1H0LwYFknhUhAwcE8ANa3CgELIQfH1MgIFiEcpDAhhgA+MET3mUMBHO2n0-D6oAMlBqCAIfIc3HlEIl1QVxogod3SZGf6LW9Bd9HH9fSbY4GySR+S7Jw7LxFj7ez+zimub7mXfzBX6dcwFFaEpglBEkRRWV5kxbFcXxGBCWJdU+hdCkdVpc59RJUwcCvDB6BgRRGygMACH-CjiltYAxDCEtbjwkhP2gDkUTQJjrWKR9ikPWAAGEoQAL3kdASLIwRL3USTfjoucjzuQScCElioAvX55CUoSAUdfl7z4mAABFVkbUSiPEsB8CKTlpOshIeGwCymBfIEZK4OxtAvLgyCeVEKHRWCST6e8RiWcDZmheV4IYLd1mQJ8YLVTZ0O1AAWPhDmwiQIgAUSgCAzN4VRlDc7gjGyhi8ogN4AGkyLkNAqpUNQ9MdN87iq1S2MMRr8q4myPKiVCqtA8U4Ug6VEkSqLFWVJDVSClKqSw4AgA"&gt;Playground link for all code here.&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In TypeScript you can reference the &lt;em&gt;type&lt;/em&gt; of an object property using the  square bracket notation. &lt;/p&gt;

&lt;p&gt;eg:&lt;br&gt;
&lt;/p&gt;

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

&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;Foo&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="na"&gt;a&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;b&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="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;A&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Foo&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;a&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt; &lt;span class="c1"&gt;//string &lt;/span&gt;
&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;B&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Foo&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;b&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt; &lt;span class="c1"&gt;//number&lt;/span&gt;
&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;ObjOne&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Foo&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt; &lt;span class="c1"&gt;//null; &lt;/span&gt;

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



&lt;p&gt;This also works for arrays&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight typescript"&gt;&lt;code&gt;
&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;MyArray&lt;/span&gt; &lt;span class="o"&gt;=&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="kr"&gt;number&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="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;Zero&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;MyArray&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;//string &lt;/span&gt;
&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;One&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;MyArray&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt; &lt;span class="c1"&gt;//number&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Now according to the &lt;a href="https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-1.html"&gt;TypeScript documentation&lt;/a&gt; the &lt;code&gt;keyof&lt;/code&gt; keyword returns a union type of all of those possible keys, which also includes the Array.prototype methods such as &lt;code&gt;reduce&lt;/code&gt;, &lt;code&gt;map&lt;/code&gt; etc.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;Reduce&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;MyArray&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;reduce&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt; &lt;span class="c1"&gt;//type Reduce = {    (callbackfn: (previousValue: 0 | "one" | ..... &lt;/span&gt;
&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;Length&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;MyArray&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;length&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="c1"&gt;//3&lt;/span&gt;

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



&lt;p&gt;This works for ordinary objects too, but there aren't many useful native methods that exist on an object instance's prototype (Object.values etc exist as static functions on the class prototype):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;ToString&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Foo&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;toString&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;gt; string&lt;/span&gt;
&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;Values&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Foo&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;values&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt; &lt;span class="c1"&gt;//Property 'values' does not exist on type 'Foo'.(2339)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Now where this gets interesting is that as well as referencing the types of properties via a string or number literal as an index - we can also reference them by a given &lt;em&gt;type&lt;/em&gt; as an index. However, in this current example, it only works for the &lt;code&gt;number&lt;/code&gt; type on arrays only:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;RefObjectByTypeNumber&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Foo&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;//Type 'Foo' has no matching index signature for type 'number'.(2537)&lt;/span&gt;
&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;RefObjectByTypeString&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Foo&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;//Type 'Foo' has no matching index signature for type 'number'.(2537)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;





&lt;div class="highlight"&gt;&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;RefArrayByTypeNumber&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;MyArray&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;//string | number&lt;/span&gt;
&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;RefArrayByTypeString&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;MyArray&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;//Type 'MyArray' has no matching index signature for type 'string'.(2537)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;If we declare an object by explicitly declaring the types of the keys, this does work:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;Bar&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&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="kr"&gt;string&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;type&lt;/span&gt; &lt;span class="nx"&gt;RefBarByTypeString&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Bar&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;//string&lt;/span&gt;

&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;Chaz&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="kr"&gt;number&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="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;RefChazByTypeNumber&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Chaz&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;//number&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;If we declare the object keys directly as string literals, this does not work:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;Eep&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;a&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="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;type&lt;/span&gt; &lt;span class="nx"&gt;RefEepByKeyA&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Eep&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;a&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt; &lt;span class="c1"&gt;//number&lt;/span&gt;
&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;RefEepByTypeString&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Eep&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;// Type 'Eep' has no matching index signature for type 'string'.(2537)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;It's not possible to declare both types as keys:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;Donk&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="na"&gt;keya&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="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="na"&gt;keyb&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="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;//Numeric index type 'number' is not assignable to string index type 'string'.(2413)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Not that I necessarily want to do that. &lt;/p&gt;

&lt;p&gt;So my main question here  is - &lt;strong&gt;what's actually going on with how we can use types as an index - but only in specific circumstances?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The documentation from Typescript isn't particularly clear here - the only references in the documentation that I can find is is this part on index types: &lt;br&gt;
&lt;a href="https://www.typescriptlang.org/docs/handbook/advanced-types.html#index-types"&gt;https://www.typescriptlang.org/docs/handbook/advanced-types.html#index-types&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;which doesn't actual demonstrate using a type as an index, &lt;/p&gt;

&lt;p&gt;and the example given here in the &lt;code&gt;keyof&lt;/code&gt; documentation: &lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-1.html"&gt;https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-1.html&lt;/a&gt;&lt;/p&gt;

</description>
      <category>typescript</category>
    </item>
    <item>
      <title>Immutable OO?</title>
      <dc:creator>David Johnston</dc:creator>
      <pubDate>Fri, 27 Mar 2020 03:03:16 +0000</pubDate>
      <link>https://dev.to/dwjohnston/immutable-oo-5a34</link>
      <guid>https://dev.to/dwjohnston/immutable-oo-5a34</guid>
      <description>&lt;p&gt;&lt;a href="https://www.destroyallsoftware.com/talks/boundaries"&gt;This talk here&lt;/a&gt; by Gary Bernhardt has got me thinking. &lt;/p&gt;

&lt;p&gt;He's basically proposing what I'd call immutable object-oriented programming, where, you have model objects that contain both data, and functions, but the data is immutable. &lt;/p&gt;

&lt;p&gt;When you do need to mutate some data, it returns a new object.&lt;/p&gt;

&lt;p&gt;And you bundle that immutable data with helper functions that apply to just that data.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class Foo {
    private data; 
    constructor(data){
        this.data = data; 
    }

    setX(x){
         return new Foo({...this.data, x}); 
    }

    toString() {
        return `This is a Foo object with value x: ${this.data.x}`; 
    }
}

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

&lt;/div&gt;



&lt;p&gt;This has the advantages of easy testing, as your Object functions can still be considered pure:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    const object = new Foo({x:1}); 
    expect(object.toString).toBe("This is a Foo object with value x: 1"); 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And reduces a lot of cognitive load that a functional paradigm has where your data, and your functions that use that data are different things. &lt;/p&gt;

&lt;p&gt;Eg, the equivalent code for this would be:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   setXOnFoo(foo, x) {
      return {...foo, x};  
   }

   stringifyFoo(foo) {
        return `This is a Foo object with value x: ${foo.x}`; 
   }

   const foo = {x: 1}; 
   expect(stringifyFoo(foo)).toBe("This is a Foo object with value x: 1"); 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the scenario where the &lt;code&gt;stringifyFoo&lt;/code&gt; method is only intended to be used with objects that fit Foo's shape, in the least, by adding those functions to the object means that your IDE is going to be helpful in telling you those methods straight away. &lt;/p&gt;

&lt;p&gt;My question is - how well explored is this concept - does it have a different name? &lt;/p&gt;

&lt;p&gt;What advantage would function programming have over this? &lt;/p&gt;

&lt;p&gt;There is a similar, &lt;a href="https://softwareengineering.stackexchange.com/questions/232711/complete-immutability-and-object-oriented-programming"&gt;well received question about this on softwareengineering.stackexchange&lt;/a&gt;. &lt;/p&gt;

</description>
      <category>immutability</category>
      <category>oop</category>
    </item>
    <item>
      <title>What do you call the style of monorepo that Babel and Material-UI use?</title>
      <dc:creator>David Johnston</dc:creator>
      <pubDate>Fri, 27 Mar 2020 00:32:38 +0000</pubDate>
      <link>https://dev.to/dwjohnston/what-do-you-call-the-style-of-monorepo-that-babel-and-material-ui-use-4792</link>
      <guid>https://dev.to/dwjohnston/what-do-you-call-the-style-of-monorepo-that-babel-and-material-ui-use-4792</guid>
      <description>&lt;p&gt;Both &lt;a href="https://github.com/babel/babel"&gt;Babel&lt;/a&gt; and &lt;a href="https://github.com/mui-org/material-ui"&gt;Material-UI&lt;/a&gt; are lerna monorepos. &lt;/p&gt;

&lt;p&gt;They both have something in common where they install a lot of common dev dependencies at the project root - jest, babel, eslint etc. &lt;/p&gt;

&lt;p&gt;Material-UI does a thing, where a given package's build scripts reference build scripts and configs at the project root:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    "build": "yarn build:cjs &amp;amp;&amp;amp; yarn build:esm &amp;amp;&amp;amp; yarn build:es &amp;amp;&amp;amp; yarn build:umd &amp;amp;&amp;amp; yarn build:copy-files",
    "build:cjs": "cross-env NODE_ENV=production BABEL_ENV=cjs babel --config-file ../../babel.config.js ./src --out-dir ./build --ignore \"**/*.test.js\"",
    "build:esm": "cross-env NODE_ENV=production BABEL_ENV=esm babel --config-file ../../babel.config.js ./src --out-dir ./build/esm --ignore \"**/*.test.js\"",
    "build:es": "cross-env NODE_ENV=production BABEL_ENV=es babel --config-file ../../babel.config.js ./src --out-dir ./build/es --ignore \"**/*.test.js\"",
    "build:umd": "cross-env BABEL_ENV=production-umd rollup -c scripts/rollup.config.js",
    "build:copy-files": "node ../../scripts/copy-files.js",
    "prebuild": "rimraf build",
    "release": "yarn build &amp;amp;&amp;amp; npm publish build --tag latest",
    "test": "cd ../../ &amp;amp;&amp;amp; cross-env NODE_ENV=test mocha 'packages/material-ui/**/*.test.js' --exclude '**/node_modules/**'",
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Babel's packages don't even have build scripts, instead they are built via  make files at the project root. &lt;/p&gt;

&lt;p&gt;Additionally, both are using yarn, which has its own concept of workspaces. &lt;/p&gt;

&lt;p&gt;What I'm wondering is how this fits in with monorepo design in general. &lt;/p&gt;

&lt;p&gt;For example it makes sense that you would want a consistent code style across all of your monorepo, so eslint defined in the root makes sense. &lt;/p&gt;

&lt;p&gt;However, in the case that your monorepo is a 'frontend/backend/common' type project - there are going to be linting rules (eg. React specific) that only apply to frontend, so this isn't necessarily always going to work. (I suppose you could have two different eslint configs in the root). &lt;/p&gt;

&lt;p&gt;I think I've had a fundamental misunderstanding about monorepos - I had thought that basically each package in a monorepo should stand in its own right - that is, you should be able to checkout the project and build and test just the one package. &lt;/p&gt;

&lt;p&gt;The idea being, that a project may have different teams, different ways of working, and so working on one package shouldn't require knowledge about how the other package works. However, the packages to have dependencies on each other, and you want that to 'just work' in development, which is where I've found lerna helpful. &lt;/p&gt;

&lt;p&gt;This certainly isn't really the case with Babel - there are no build scripts in the packages, and at the project root just a single 'build' script. You would have to be diving into the make files to be building an individual package. &lt;/p&gt;

&lt;p&gt;Can someone outline some of the key concepts people use to think about monorepos? &lt;/p&gt;

&lt;p&gt;eg. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Common tooling at project root&lt;/li&gt;
&lt;li&gt;What a standard 'getting started' flow looks like for a developer freshly checking out the project is. &lt;/li&gt;
&lt;li&gt;What a standard build pipeline flow looks like. (My understanding for example just force publishes all packages, regardless of changes, and keeps all their versions in sync like that). &lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>architecture</category>
      <category>monorepo</category>
      <category>lerna</category>
      <category>javascript</category>
    </item>
    <item>
      <title>What do you call modern (frontend?) dependency architecture? </title>
      <dc:creator>David Johnston</dc:creator>
      <pubDate>Thu, 12 Mar 2020 23:24:14 +0000</pubDate>
      <link>https://dev.to/dwjohnston/what-do-you-call-modern-frontend-dependency-architecture-2enl</link>
      <guid>https://dev.to/dwjohnston/what-do-you-call-modern-frontend-dependency-architecture-2enl</guid>
      <description>&lt;p&gt;If I google 'dependency architecture' I get a bunch of results like &lt;a href="https://www.informit.com/articles/article.aspx?p=2832399"&gt;this one&lt;/a&gt;, which has either this circle model: &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--FyqHfNpG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/mgrubkrsb5h9e45qe8f1.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--FyqHfNpG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/mgrubkrsb5h9e45qe8f1.jpg" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Or this n-tier layered one. (To be fair, the &lt;a href="https://rules.ssw.com.au/do-you-use-a-dependency-injection-centric-architecture"&gt;source of this image&lt;/a&gt; is criticising this approach for not supporting dependency injection). &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--phOUbV22--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/b46a3l4ehqs2popxg22e.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--phOUbV22--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/b46a3l4ehqs2popxg22e.jpg" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It seems to me that these diagrams are more relevant to conventional monoliths, where you seperate out your data access logic, your application logic, your frontend logic. &lt;/p&gt;

&lt;p&gt;However, I'm thinking about in the context of microservices, and modern SPAs where there's a lot more logic happening on the frontend. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://youtu.be/TqfbAXCCVwE?t=907"&gt;This talk by Monica Lent&lt;/a&gt;, where she's talking specifically about frontend architecture is what I have in mind. &lt;/p&gt;

&lt;p&gt;Any suggestions, new key words to google? Or is the onion/n-tier architecture just are relevant to microservices and SPAs? &lt;/p&gt;

</description>
      <category>architecture</category>
      <category>javascript</category>
    </item>
  </channel>
</rss>
