<?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: Wolk Software</title>
    <description>The latest articles on DEV Community by Wolk Software (@wolksoftware).</description>
    <link>https://dev.to/wolksoftware</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%2Forganization%2Fprofile_image%2F467%2Fc0144899-f135-470b-b7ef-2a0b29c1337e.png</url>
      <title>DEV Community: Wolk Software</title>
      <link>https://dev.to/wolksoftware</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/wolksoftware"/>
    <language>en</language>
    <item>
      <title>Getting started with Azure functions v4 + Node.js &amp; TypeScript</title>
      <dc:creator>Remo H. Jansen</dc:creator>
      <pubDate>Tue, 02 May 2023 08:51:54 +0000</pubDate>
      <link>https://dev.to/wolksoftware/getting-started-with-azure-functions-v4-nodejs-typescript-439e</link>
      <guid>https://dev.to/wolksoftware/getting-started-with-azure-functions-v4-nodejs-typescript-439e</guid>
      <description>&lt;h2&gt;
  
  
  In this post, we are going to take a look at everything you need to know to get started with Azure Functions v4 (currently in preview). We will also take a look at some common use cases.
&lt;/h2&gt;

&lt;h3&gt;
  
  
  What are Azure functions?
&lt;/h3&gt;

&lt;p&gt;An Azure Function App is a serverless compute service provided by Microsoft Azure, which allows developers to easily create and deploy small pieces of code, known as "functions," that can be executed in response to events or triggers. Azure Function Apps can be written in a variety of languages, including C#, F#, JavaScript, PowerShell, Python, and TypeScript.&lt;/p&gt;

&lt;p&gt;The main advantage of Azure Function Apps over traditional API apps is that they are fully managed and scalable, meaning developers can focus on writing the code for the specific task at hand, without worrying about the underlying infrastructure or server management. Azure Function Apps are also pay-per-use, which means that developers only pay for the resources they consume while their functions are running, and they don't have to worry about paying for idle time or unused resources.&lt;/p&gt;

&lt;p&gt;Azure Function Apps is that they can be integrated with a wide range of other Azure services, such as Azure Storage, Azure Event Hubs, Azure Service Bus, and Azure Cosmos DB, making it easy to build complex applications that leverage multiple Azure services. Additionally, Azure Function Apps can be used to build event-driven architectures, where functions can be triggered by events such as changes to a database, the arrival of a message in a queue, or the upload of a file to a storage account. This allows for highly scalable and reactive applications that can respond to changes in real-time.&lt;/p&gt;

&lt;h3&gt;
  
  
  What is exciting about Azure functions v4?
&lt;/h3&gt;

&lt;p&gt;Version 4 was designed with the following goals in mind:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Provide a familiar and intuitive experience to Node.js developers&lt;/li&gt;
&lt;li&gt;Make the file structure flexible with support for full customization&lt;/li&gt;
&lt;li&gt;Switch to a code-centric approach for defining function configuration&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;The Node.js "programming model" shouldn't be confused with the Azure Functions "runtime".&lt;br&gt;
Programming model: Defines how you author your code and is specific to JavaScript and TypeScript.&lt;br&gt;
Runtime: Defines underlying behavior of Azure Functions and is shared across all languages.&lt;/p&gt;

&lt;p&gt;The programming model version is strictly tied to the version of the @azure/functions npm package, and is versioned independently of the runtime. Both the runtime and the programming model use "4" as their latest major version, but that is purely a coincidence.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The V4 model uses an app object as the entry point for registering functions instead of &lt;code&gt;function.json&lt;/code&gt; files. For example, to register an HTTP trigger responding to a GET request, you can call &lt;code&gt;app.http()&lt;/code&gt; or &lt;code&gt;app.get()&lt;/code&gt; which was modeled after other Node.js frameworks like Express.js that also support &lt;code&gt;app.get()&lt;/code&gt;. &lt;/p&gt;

&lt;h4&gt;
  
  
  HttpTrigger Handler (v3)
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&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="k"&gt;async&lt;/span&gt; &lt;span class="nf"&gt;function &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;context&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;context&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;HTTP function processed a request&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;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;query&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;
    &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;
    &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;world&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="nx"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;res&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`Hello, &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="s2"&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;h4&gt;
  
  
  HttpTrigger Bindings (v3)
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"bindings"&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="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"authLevel"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"anonymous"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"httpTrigger"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"direction"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"in"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"req"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"methods"&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="s2"&gt;"get"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="s2"&gt;"post"&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;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"http"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"direction"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"out"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"res"&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;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;h4&gt;
  
  
  HttpTrigger Handler + Bindings (v4)
&lt;/h4&gt;

&lt;p&gt;Trigger configuration like methods and authLevel that were specified in a &lt;code&gt;function.json&lt;/code&gt; file before are moved to the code itself in V4. V4 also sets several defaults for you, which is why you don't see &lt;code&gt;authLevel&lt;/code&gt; or an &lt;code&gt;output&lt;/code&gt; binding in the V4 example.&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="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;app&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@azure/functions&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;http&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;helloWorld1&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="na"&gt;methods&lt;/span&gt;&lt;span class="p"&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;GET&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;POST&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="na"&gt;handler&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;context&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;context&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Http function processed request&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;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;query&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&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="p"&gt;)&lt;/span&gt; 
      &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;text&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; 
      &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;world&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="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`Hello, &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="s2"&gt;!`&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The V4 model, have adjusted the HTTP request and response types to be a subset of the fetch standard instead of types unique to Azure Functions. V4 uses Node.js's undici package, which follows the fetch standard and is currently being integrated into Node.js core.&lt;/p&gt;

&lt;h4&gt;
  
  
  HttpRequest - body (v3)
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// returns a string, object, or Buffer&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;body&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="c1"&gt;// returns a string&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;body&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;rawBody&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="c1"&gt;// returns a Buffer&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;body&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;bufferBody&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="c1"&gt;// returns an object representing a form&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;body&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;parseFormBody&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  HttpRequest - body (v4)
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;body&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;text&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;body&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&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;body&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;formData&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;body&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;arrayBuffer&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;body&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;blob&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  HttpResponse – status (v3)
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;status&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;res&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nx"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;res&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;statusCode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;200&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="na"&gt;status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;200&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="na"&gt;statusCode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  HttpResponse – status (v4)
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Folder structure (v3)
&lt;/h4&gt;

&lt;p&gt;The required folder structure for a JavaScript project in V3 looks like the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;FunctionsProject
 | - MyFirstFunction
 | | - index.js
 | | - function.json
 | - MySecondFunction
 | | - index.js
 | | - function.json
 | - SharedCode
 | | - myFirstHelperFunction.js
 | | - mySecondHelperFunction.js
 | - node_modules
 | - host.json
 | - package.json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Folder structure (v4)
&lt;/h4&gt;

&lt;p&gt;The recommended folder structure for a JavaScript project in V4 looks like the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;project_root&amp;gt;/
 | - .vscode/
 | - src/
 | | - functions/
 | | | - myFirstFunction.js
 | | | - mySecondFunction.js
 | - test/
 | | - functions/
 | | | - myFirstFunction.test.js
 | | | - mySecondFunction.test.js
 | - .funcignore
 | - host.json
 | - local.settings.json
 | - package.json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;⚠️ Keep in mind that you can't mix the v3 and v4 programming models in the same function app. As soon as you register one v4 function in your app, any v3 functions registered in function.json files are ignored.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Create a new Azure function v4 project
&lt;/h3&gt;

&lt;p&gt;The version 4 of the Node.js programming model requires the following minimum versions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;@azure/functions npm package v4.0.0-alpha.9+&lt;/li&gt;
&lt;li&gt;Node.js v18+&lt;/li&gt;
&lt;li&gt;TypeScript v4+&lt;/li&gt;
&lt;li&gt;Azure Functions Runtime v4.16+&lt;/li&gt;
&lt;li&gt;Azure Functions Core Tools v4.0.5095+&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In Azure Functions, a function project is a container for one or more individual functions that each responds to a specific trigger. All functions in a project share the same local and hosting configurations.&lt;/p&gt;

&lt;p&gt;Run the &lt;code&gt;func init&lt;/code&gt; command, as follows, to create a functions project in a folder named &lt;code&gt;MyFunctionApp&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;func init MyFunctionApp &lt;span class="nt"&gt;--model&lt;/span&gt; V4
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The command prompts you to select a runtime and language. Select &lt;code&gt;node&lt;/code&gt; and &lt;code&gt;typescript&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;Select a number &lt;span class="k"&gt;for &lt;/span&gt;worker runtime:
1. dotnet
2. dotnet &lt;span class="o"&gt;(&lt;/span&gt;isolated process&lt;span class="o"&gt;)&lt;/span&gt;
3. node
4. python
5. powershell
6. custom
Choose option: 3
node
Select a number &lt;span class="k"&gt;for &lt;/span&gt;language:
1. javascript
2. typescript
Choose option: 2
typescript
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Enable the v4 programming model
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;⚠️ During the V4 preview, you must set the app setting &lt;code&gt;AzureWebJobsFeatureFlags&lt;/code&gt; to &lt;code&gt;EnableWorkerIndexing&lt;/code&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The following application setting is required to run the v4 programming model while it is in preview:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Name: &lt;code&gt;AzureWebJobsFeatureFlags&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Value: &lt;code&gt;EnableWorkerIndexing&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you're running locally using Azure Functions Core Tools, you should add this setting to your &lt;code&gt;local.settings.json&lt;/code&gt; file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"IsEncrypted"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"Values"&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;"FUNCTIONS_WORKER_RUNTIME"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"node"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"AzureWebJobsFeatureFlags"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"EnableWorkerIndexing"&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;&amp;lt;--&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;HERE!&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"AzureWebJobsStorage"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&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="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;If you're running in Azure, follow these steps with the tool of your choice:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;az functionapp config appsettings &lt;span class="nb"&gt;set&lt;/span&gt; &lt;span class="nt"&gt;--name&lt;/span&gt; &amp;lt;FUNCTION_APP_NAME&amp;gt;  &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;--resource-group&lt;/span&gt; &amp;lt;RESOURCE_GROUP_NAME&amp;gt;  &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;--settings&lt;/span&gt; &lt;span class="nv"&gt;AzureWebJobsFeatureFlags&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;EnableWorkerIndexing
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Create a new function
&lt;/h3&gt;

&lt;p&gt;Navigate into the project folder:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd &lt;/span&gt;MyFunctionApp
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This folder contains various files for the project, including configurations files named local.settings.json and host.json. Because local.settings.json can contain secrets downloaded from Azure, the file is excluded from source control by default in the .gitignore file.&lt;/p&gt;

&lt;p&gt;Add a function to your project by using the following command:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;Choose the template for &lt;code&gt;HTTP trigger&lt;/code&gt;. You can keep the default name (&lt;code&gt;httpTrigger&lt;/code&gt;) or give it a new name (&lt;code&gt;HttpExample&lt;/code&gt;). Your function name must be unique, or you're asked to confirm if your intention is to replace an existing function. You can find the function you added in the &lt;code&gt;src/functions&lt;/code&gt; directory.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;Select a number &lt;span class="k"&gt;for &lt;/span&gt;template:
1. Azure Blob Storage trigger
2. Azure Cosmos DB trigger
3. Durable Functions entity
4. Durable Functions orchestrator
5. Azure Event Grid trigger
6. Azure Event Hub trigger
7. HTTP trigger
8. Azure Queue Storage trigger
9. Azure Service Bus Queue trigger
10. Azure Service Bus Topic trigger
11. Timer trigger
Choose option: 7
HTTP trigger
Function name: &lt;span class="o"&gt;[&lt;/span&gt;httpTrigger] 
Creating a new file /src/functions/httpTrigger.ts
The &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="s2"&gt;"httpTrigger"&lt;/span&gt; was created successfully from the &lt;span class="s2"&gt;"HTTP trigger"&lt;/span&gt; template.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The function will be created under &lt;code&gt;/src/functions/httpTrigger.ts&lt;/code&gt; as follows:&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="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;HttpRequest&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;HttpResponseInit&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;InvocationContext&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;@azure/functions&lt;/span&gt;&lt;span class="dl"&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;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;httpTrigger&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;request&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;HttpRequest&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;context&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;InvocationContext&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;HttpResponseInit&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;context&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;`Http function processed request for url "&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;url&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;query&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&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="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;text&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;world&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="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`Hello, &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="s2"&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;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;http&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;httpTrigger&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="na"&gt;methods&lt;/span&gt;&lt;span class="p"&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;GET&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;POST&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="na"&gt;authLevel&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;anonymous&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;handler&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;httpTrigger&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We now need to add Azure Storage connection information in &lt;code&gt;local.settings.json&lt;/code&gt;. If you don't have an Azure Storage account, you can use the Azurite to run a local storage emulator. You can install Azurite using the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-g&lt;/span&gt; azurite
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can then start Azurite by running the following command:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;The easiest way to connect to the emulator from your application is to configure a connection string in your application's configuration file that references the shortcut &lt;code&gt;UseDevelopmentStorage=true&lt;/code&gt;. The shortcut is equivalent to the full connection string for the emulator. In your Azure Functions project, open the &lt;code&gt;local.settings.json&lt;/code&gt; file and update the connection string for your storage account:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"IsEncrypted"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"Values"&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;"FUNCTIONS_WORKER_RUNTIME"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"node"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"AzureWebJobsFeatureFlags"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"EnableWorkerIndexing"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"AzureWebJobsStorage"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"UseDevelopmentStorage=true;DevelopmentStorageProxyUri=http://127.0.0.1:10000"&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;&amp;lt;--&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;HERE!&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;Run your function by starting the local Azure Functions runtime host from the &lt;code&gt;MyFunctionApp&lt;/code&gt; folder.&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;The following output must appear:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;Azure Functions Core Tools
Core Tools Version:       4.0.5095 Commit &lt;span class="nb"&gt;hash&lt;/span&gt;: N/A  &lt;span class="o"&gt;(&lt;/span&gt;64-bit&lt;span class="o"&gt;)&lt;/span&gt;
Function Runtime Version: 4.16.5.20396

&lt;span class="o"&gt;[&lt;/span&gt;2023-04-14T19:50:22.069Z] Worker process started and initialized.
...
Functions:

        httpTrigger: &lt;span class="o"&gt;[&lt;/span&gt;GET,POST] http://localhost:7071/api/httpTrigger

For detailed output, run func with &lt;span class="nt"&gt;--verbose&lt;/span&gt; flag.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Deploying your function app to Azure
&lt;/h3&gt;

&lt;p&gt;First, you need to build your function app. This will create a &lt;code&gt;dist&lt;/code&gt; folder with the compiled JavaScript files:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;Then, you need to create a ZIP file with the content of the &lt;code&gt;dist&lt;/code&gt; folder, and the &lt;code&gt;host.json&lt;/code&gt; and &lt;code&gt;package.json&lt;/code&gt; files. You can use the following commands to do so:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;rm&lt;/span&gt; &lt;span class="nt"&gt;-r&lt;/span&gt; ./dist/&lt;span class="k"&gt;**&lt;/span&gt;/&lt;span class="k"&gt;*&lt;/span&gt;.map
&lt;span class="nb"&gt;cp&lt;/span&gt; &lt;span class="nt"&gt;-r&lt;/span&gt; ./host.json ./package.json ./node_modules ./dist
&lt;span class="nb"&gt;rm&lt;/span&gt; &lt;span class="nt"&gt;-r&lt;/span&gt; ./dist/node_modules/@types/
&lt;span class="nb"&gt;rm&lt;/span&gt; &lt;span class="nt"&gt;-r&lt;/span&gt; ./dist/node_modules/azure-functions-core-tools/
&lt;span class="nb"&gt;rm&lt;/span&gt; &lt;span class="nt"&gt;-r&lt;/span&gt; ./dist/node_modules/typescript/
&lt;span class="nb"&gt;cd&lt;/span&gt; ./dist
&lt;span class="nb"&gt;mkdir &lt;/span&gt;dist
&lt;span class="nb"&gt;mv&lt;/span&gt; ./src ./dist/
zip &lt;span class="nt"&gt;-r&lt;/span&gt; ../deploy.zip ./&lt;span class="k"&gt;*&lt;/span&gt;
&lt;span class="nb"&gt;cd&lt;/span&gt; ..
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After running these commands, you should have a &lt;code&gt;deploy.zip&lt;/code&gt; file in your project folder, with the following contents:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;.
├── dist
│   └── src
│       └── functions
│           └── httpTrigger.js
├── host.json
├── package.json
└── node-modules
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can deploy the &lt;code&gt;deploy.zip&lt;/code&gt; file to Azure using the Azure CLI:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;az login
az account &lt;span class="nb"&gt;set&lt;/span&gt; &lt;span class="nt"&gt;--subscription&lt;/span&gt; YOUR-AZURE-SUBSCRIPTION-ID
az functionapp deployment &lt;span class="nb"&gt;source &lt;/span&gt;config-zip &lt;span class="nt"&gt;-g&lt;/span&gt; YOUR-RESOURCE-GROUP &lt;span class="nt"&gt;-n&lt;/span&gt; YOUR-FUNCTION-APP &lt;span class="nt"&gt;--src&lt;/span&gt; ./deploy.zip
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Recipe 1: Working with environment variables
&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;az functionapp config appsettings list&lt;/code&gt; command returns the existing application settings, as in the following example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;az functionapp config appsettings list &lt;span class="nt"&gt;--name&lt;/span&gt; &amp;lt;FUNCTION_APP_NAME&amp;gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;--resource-group&lt;/span&gt; &amp;lt;RESOURCE_GROUP_NAME&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;az functionapp config appsettings set&lt;/code&gt; command adds or updates an application setting. The following example creates a setting with a key named &lt;code&gt;CUSTOM_FUNCTION_APP_SETTING&lt;/code&gt; and a value of &lt;code&gt;12345&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;az functionapp config appsettings &lt;span class="nb"&gt;set&lt;/span&gt; &lt;span class="nt"&gt;--name&lt;/span&gt; &amp;lt;FUNCTION_APP_NAME&amp;gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;--resource-group&lt;/span&gt; &amp;lt;RESOURCE_GROUP_NAME&amp;gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;--settings&lt;/span&gt; &lt;span class="nv"&gt;CUSTOM_FUNCTION_APP_SETTING&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;12345
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The function app settings values can also be read in your code as environment variables:&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="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;CUSTOM_FUNCTION_APP_SETTING&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When run develop a function app locally, you must maintain local copies of these values in the &lt;code&gt;local.settings.json&lt;/code&gt; project file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"IsEncrypted"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"Values"&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;"FUNCTIONS_WORKER_RUNTIME"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"node"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"AzureWebJobsFeatureFlags"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"EnableWorkerIndexing"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"AzureWebJobsStorage"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"UseDevelopmentStorage=true;DevelopmentStorageProxyUri=http://127.0.0.1:10000"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"CUSTOM_FUNCTION_APP_SETTING"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;12345&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;&amp;lt;--&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;HERE!&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;h3&gt;
  
  
  Recipe 2: Accessing Azure resources from your function
&lt;/h3&gt;

&lt;p&gt;If your application access other resources in Azure, you will need to create an application identity and grant it access to those resources. For example, you might want to access a Key Vault to retrieve secrets. You can do so by using the &lt;code&gt;@azure/identity&lt;/code&gt; and &lt;code&gt;@azure/keyvault-secrets&lt;/code&gt; packages:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;yarn add @azure/identity @azure/keyvault-secrets
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then, you can write a function that retrieves a secret from Key Vault. The following example uses the &lt;code&gt;DefaultAzureCredential&lt;/code&gt; class to authenticate with Azure Active Directory and then retrieves a secret from Key Vault:&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="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;DefaultAzureCredential&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;@azure/identity&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;SecretClient&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;@azure/keyvault-secrets&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;AppSecrets&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// your secrets here&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;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;getSecrets&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;AppSecrets&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;keyVaultName&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;your-key-vault-name&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;KVUri&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`https://&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;keyVaultName&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;.vault.azure.net`&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;secretName&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;your-secret-name&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;credential&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;DefaultAzureCredential&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// &amp;lt;-- HERE!&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;SecretClient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;KVUri&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;credential&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;retrievedSecret&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getSecret&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;secretName&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;retrievedSecret&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="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="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;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&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;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;parse&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="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;If you run the previous code in an Azure function, it will fail because you need to create an application identity first. You can do so in the Azure portal:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2F3iaq0728ob178wtaoj8d.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2F3iaq0728ob178wtaoj8d.png" alt="application identity" width="800" height="817"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then, you need to grant the application identity access to the Key Vault:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fm57fyjzj6kdmoe1xmxje.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fm57fyjzj6kdmoe1xmxje.png" alt="application identity access to the Key Vault" width="800" height="326"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Recipe 3: Working with Cosmos DB
&lt;/h3&gt;

&lt;p&gt;You can use the &lt;code&gt;@azure/cosmos&lt;/code&gt; package to access Cosmos DB from your function app. You could store your Cosmos DB connection string in the application settings, but it is better to store it in Key Vault and retrieve it using the &lt;code&gt;getSecrets&lt;/code&gt; function from the previous recipe.&lt;/p&gt;

&lt;p&gt;The following function retrieves the Cosmos DB connection string from Key Vault and then uses it to create a Cosmos DB configuration object:&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="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;getSecrets&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;./secrets&lt;/span&gt;&lt;span class="dl"&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;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;getDatabaseConfig&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;containerId&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;log&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;txt&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="k"&gt;void&lt;/span&gt;&lt;span class="p"&gt;)&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Invoking getDatabaseConfig...&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;appSecrets&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;getSecrets&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="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;endpoint&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;appSecrets&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;cosmosEndpoint&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="nx"&gt;appSecrets&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;cosmosKey&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;databaseId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;wolkdotcomui&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;containerId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;containerId&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;You can then use the &lt;code&gt;getDatabaseConfig&lt;/code&gt; function to create a Cosmos DB client and retrieve a container. You will need to install the &lt;code&gt;@azure/cosmos&lt;/code&gt; package:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;yarn add @azure/cosmos
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The following function creates a Cosmos DB client and then retrieves a container:&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="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Container&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;CosmosClient&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;@azure/cosmos&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;getDatabaseConfig&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;./config&lt;/span&gt;&lt;span class="dl"&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;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;getDbContainer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;containerId&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;log&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;txt&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="k"&gt;void&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Container&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;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Invoking getDbContainer... &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;containerId&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;dbConfig&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;getDatabaseConfig&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;containerId&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="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;endpoint&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;databaseId&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;dbConfig&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;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;CosmosClient&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
        &lt;span class="nx"&gt;endpoint&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;database&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;database&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;databaseId&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;container&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;database&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;container&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;containerId&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;container&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 container can then be used to retrieve items from Cosmos DB. For example, the following function retrieves a user from a container named &lt;code&gt;users&lt;/code&gt; in Cosmos DB:&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="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;getDbContainer&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;../shared/db&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;User&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;id&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;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;email&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="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;getUserById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;id&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="nb"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;User&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;containerId&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;users&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;dbContainer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;getDbContainer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;containerId&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;item&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;dbContainer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;item&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;id&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;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&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;read&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;User&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="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;resource&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;User not found&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="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;resource&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;You can then use the &lt;code&gt;getUserById&lt;/code&gt; in your functions.&lt;/p&gt;

&lt;h3&gt;
  
  
  Recipe 4: Troubleshooting deployments
&lt;/h3&gt;

&lt;p&gt;If after deploying your function app your application is not working you should head to the azure portal and check a few things:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Check the logs in the &lt;code&gt;Log stream&lt;/code&gt; section of the portal.&lt;/li&gt;
&lt;li&gt;Try to restart the function app from the &lt;code&gt;Overview&lt;/code&gt; section.&lt;/li&gt;
&lt;li&gt;Visit the &lt;code&gt;App Service Editor (Preview)&lt;/code&gt; section of the portal to see the deployed files.&lt;/li&gt;
&lt;li&gt;Visit the &lt;code&gt;Functions&lt;/code&gt; section of the portal to see the deployed functions.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can use the follwing URL to access the &lt;code&gt;Debug Console&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;https://&amp;lt;YOUR-APP-NAME&amp;gt;.scm.azurewebsites.net/DebugConsole
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To download the ZIP file of the deployed application visit:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;https://&amp;lt;YOUR-APP-NAME&amp;gt;.scm.azurewebsites.net/api/zip/site/wwwroot/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We hope that this post has been useful. If you have any questions or comments, please contact us via Twitter at &lt;a href="https://twitter.com/WolkSoftwareLtd" rel="noopener noreferrer"&gt;@WolkSoftwareLtd&lt;/a&gt;.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>The upcoming SaaS bubble burst</title>
      <dc:creator>Remo H. Jansen</dc:creator>
      <pubDate>Fri, 07 Apr 2023 10:01:01 +0000</pubDate>
      <link>https://dev.to/wolksoftware/the-upcoming-saas-bubble-burst-1c95</link>
      <guid>https://dev.to/wolksoftware/the-upcoming-saas-bubble-burst-1c95</guid>
      <description>&lt;h2&gt;
  
  
  It is 2023 and we are not feeling bullish about the future of SaaS businesses.
&lt;/h2&gt;

&lt;p&gt;It is 2023, and we are not feeling bullish on the future of SaaS businesses.&lt;/p&gt;

&lt;p&gt;The recent mainstream conversation about generative AI advancements such as ChatGPT got us thinking about some of the broader implications for the software industry. When we think that with the power of AI, a software engineer can achieve superhuman productivity levels today, the first thing that comes to mind is how AI will disrupt most SaaS businesses over the next decade.&lt;/p&gt;

&lt;h3&gt;
  
  
  Are SaaS businesses protected against the competition?
&lt;/h3&gt;

&lt;p&gt;Building a SaaS business is expensive for two main reasons.&lt;br&gt;
Experimentation. First, you need to spend a considerable amount of money doing user research until you come up with a solution that is good enough to be purchased by customers.&lt;br&gt;
Customer acquisition. Then you need to scale as fast as possible and capture as much market share as possible, spending a lot of cash on digital marketing.&lt;br&gt;
The value of some solutions is fundamentally coupled with the number of users on the platform. For example, any kind of market matching platform becomes more valuable as the number of users grows. In such cases, capturing enough market share becomes a barrier to entry for competitors and protects the business's long-term success. &lt;/p&gt;

&lt;p&gt;Other SaaS solutions, such as payment solutions, also present obstacles to competition due to the expenses associated with fraud prevention and compliance with central banks and other financial markets regulators such as the SEC or the ESMA.&lt;/p&gt;

&lt;p&gt;Most SaaS solutions don't present these barriers to entry for competitors. Think about HR, accounting, project management or marketing solutions. In most cases, the number of users on the platform is entirely irrelevant to the customers (beyond the service provider's financial stability).&lt;/p&gt;

&lt;p&gt;The principal value proposition of Saas companies is a good user experience and convenience (e.g. always available, automated updates, no need to install). One of the biggest problems is that patents do not protect most SaaS solutions. Individual algorithms must be patented, but user experience and convenience can not.&lt;/p&gt;

&lt;p&gt;The reality is that, &lt;strong&gt;in most cases, nothing is protecting SaaS businesses from competition&lt;/strong&gt; other than the initial upfront investment in experimentation and the customer acquisition costs.&lt;/p&gt;

&lt;h3&gt;
  
  
  How are SaaS businesses going to be disrupted?
&lt;/h3&gt;

&lt;p&gt;Cloud computing is mature today, and a single developer could easily manage to scale and serve millions of customers. The rise of AI can make individual developers reach superhuman levels of productivity, which means that a savvy developer can copy the user experience from an existing SaaS solution without the upfront research investment and at a fraction of the development costs. The developer would create a product with an almost identical value proposition and minimal operation costs in a matter of weeks. Indeed, the developer would not have the reputation of the original product, but the subscription price could be a fraction of the original and still be profitable. &lt;/p&gt;

&lt;p&gt;Another step to consider would be to make the product open source. The development would benefit from free community bug fixes and features, and the market would trust the product more as there would be no fear of vendor lock-in. Ultimately, the developer would only charge a small fee for convenience; &lt;strong&gt;SaaS product will "become a commodity product"&lt;/strong&gt;. The small footprint of the team and low operation costs would mean that the business has more agility and capacity to innovate than the large business.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;SaaS products will transition from a high-margin to a low-margin model&lt;/strong&gt;. As new market leaders emerge, the low margins will deter new competitors, setting up the new business for long-term success. The model might is not great incentive for investors, but it will undoubtedly disrupt the existing SaaS businesses and make the the founders wealthy.&lt;/p&gt;

&lt;h3&gt;
  
  
  What can SaaS businesses do to avoid disruption?
&lt;/h3&gt;

&lt;p&gt;First, we know that SaaS business valuations have been using crazy multiples for a long time. The extremely high valuations are not a very good starting point. The first step would be dramatically reducing operating costs and transitioning from high growth into profitability so you can reduce your margins as time goes by. The business's ultimate goal should be to charge for convenience, not a product. It would be best if the company ultimately considered open-sourcing the product.&lt;/p&gt;

&lt;p&gt;Another thing that the business should consider is to leverage the data from the existing large numbers of customers and embrace AI as soon as possible. Certain AI features require vast amounts of data and can sometimes be patented. The lack of data and the patents could protect the business against disruption from new market entrants.&lt;/p&gt;

&lt;p&gt;What do you think? Is this too far-fetched? It won't happen overnight, but time will tell; we should find out in the next 10-15 years.&lt;/p&gt;

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

</description>
      <category>saas</category>
      <category>startup</category>
    </item>
    <item>
      <title>The key to scaling your business</title>
      <dc:creator>Remo H. Jansen</dc:creator>
      <pubDate>Thu, 01 Dec 2022 00:26:57 +0000</pubDate>
      <link>https://dev.to/wolksoftware/the-key-to-scaling-your-business-56p5</link>
      <guid>https://dev.to/wolksoftware/the-key-to-scaling-your-business-56p5</guid>
      <description>&lt;p&gt;The concept of scaling a business is often used interchangeably with growing a business, but these are two distinct concepts. Take successful startups or new small businesses: Without a clear definition of scaling a business, we mistakenly think of these companies as successful because they achieved massive growth in a short period of time. The reality is when a company grows too fast; it makes itself vulnerable to a range of problems stemming from not having created a sure foundation to support rapid development. Learning how to scale a business mitigates these risks by ensuring that foundational operations are created that will support growth in the long term. &lt;/p&gt;

&lt;h2&gt;
  
  
  LEARNING HOW TO SCALE A BUSINESS
&lt;/h2&gt;

&lt;p&gt;What is scaling in business? To create a working definition of scaling a business, first, consider what it means to start and grow a business. You started your company to fill a need in your market, make a profit and likely fulfil a dream. You need to grow your business to keep it profitable and expand your market reach. Many people think of business expansion as “hockey stick growth,” where there is an initial period of linear growth. Still, once the business hits an inflexion point, revenue shoots up sharply. &lt;/p&gt;

&lt;p&gt;As alluring as rapid growth can be, entrepreneurs often place their focus on achieving it right away and lose focus on what matters. The problem with that sort of tunnel vision is that it diminishes the importance of the period of linear growth that comes before the rising handle of the hockey stick – that is, the blade. The blade typically lasts about three to four years, and it is where the most important work is being done. &lt;/p&gt;

&lt;p&gt;Scaling a business means utilizing this “blade period” to put systems and procedures into place that will prepare you for lasting, profitable development. The blade period is where you establish your core values, your company culture and your brand identity. It’s also where you will develop the client experience you want to provide and create the initial business model when you take your product or service to market. In short, it’s the make-or-break period of any business. &lt;/p&gt;

&lt;p&gt;Scaling a business is not easy to do, which is why it should be done as thoughtfully and meticulously as possible. Because in the long run, when you do hit that surging growth curve, you need as solid of a foundation as possible to hold you up. Here are the most important things to remember when figuring out how to scale a business mindfully.&lt;/p&gt;

&lt;h2&gt;
  
  
  TIPS FOR HOW TO SCALE A BUSINESS
&lt;/h2&gt;

&lt;p&gt;When we talk about scaling a business, we’re referring to strategies for growth that align with your original business vision while managing the impact of growth on your company. Implementing the following tips for how to scale a business form a sustainable scaling strategy you can rely on.  &lt;/p&gt;

&lt;h3&gt;
  
  
  1. KNOW YOUR PURPOSE
&lt;/h3&gt;

&lt;p&gt;Scaling a business is reliant on creating customer loyalty. What is the best way to create customer loyalty? Focus on employee loyalty first so they can spread the word and pass their enthusiasm for your company on to those they serve. Employees are loyal to companies whose purpose and values align with their own, so they can feel their careers have a higher purpose. Learning how to scale a business will ultimately fail if you don’t first start with your “why” of going into business in the first place. Knowing your purpose and successfully communicating that to your team is how to make them raving fans of your company and organically drive growth.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. DEVELOP A BUSINESS MAP
&lt;/h3&gt;

&lt;p&gt;Most entrepreneurs have a business plan, but have you thought about developing a business map? Business maps are an effective, comprehensive way to scale a business and meet its goals. Creating a business map prompts you to ask foundational questions such as: What business are you really in? What was your reason for getting into this business in the first place?&lt;/p&gt;

&lt;p&gt;Business maps encourage and challenge you to look at where you came from, define your purpose for starting this business and look ahead: What’s next for your business, and where does your company ideally end up? Having this sort of documentation of your goals is a crucial part of learning how to scale a business and will be a helpful reference for when times get tough.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. PERFECT YOUR PRODUCT OR SERVICE
&lt;/h3&gt;

&lt;p&gt;With their focus on massive growth, many business owners forget to ensure that their product or service is solid. They often figure that they will fix it after getting more users or more distribution. However, if you don’t work out the kinks and get rid of the bugs now, they will only get worse when you are scaling a business. This is why learning to scale a business before pursuing growth will save you headaches and money in the long run. The early years of your business is a time to listen to feedback, find issues and improve your offerings until they meet your customers’ expectations. When you focus on creating a product or service that is of excellent quality, many of your growth issues will take care of themselves. Working on the issues in your first version also helps you assume more control when you scale your business because you will have a deeper understanding of what you and your customers want and need your product or service to be.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. CREATE THOUGHTFUL PROCESSES AND OPERATIONS
&lt;/h3&gt;

&lt;p&gt;How to scale a business doesn’t just involve growing upward and outward – it also means ensuring that your internal processes and operations are functioning seamlessly. The last thing you want is to start losing customers you’ve worked so hard to acquire because some part of your infrastructure is weak. While perfecting processes, keep in mind that some of the systems and processes that work when your company is in its early stages won’t work on a massive scale. This is where adaptability and flexibility come in, as you may need to tweak processes as you grow. Establishing a framework of what works and keeps your business running smoothly in the early years is key to scaling a business because it forms a solid core. While you can always improve on this core as growth occurs, it’s much more difficult to go back and create it once you’ve grown past a certain level.&lt;/p&gt;

&lt;h3&gt;
  
  
  5. ESTABLISH YOUR TEAM
&lt;/h3&gt;

&lt;p&gt;It may seem obvious that establishing a strong team is a prerequisite for scaling a business – you can’t handle everything on your own. Developing a management team that is flexible and can grow with the company is an important component when it comes to learning how to scale a business.&lt;/p&gt;

&lt;p&gt;Your team is not just about your employees, though. To master how to scale a business sustainably, you must work on developing external relationships with suppliers, partners and other outside organizations that will be part of your overall growth. &lt;/p&gt;

&lt;p&gt;One of the best things about operating a small business is the ability to establish intimate relationships with your customers. You get to give them the experience that you want from beginning to end. And the goal should always be to create a raving fan – someone who will be a staunch advocate for your brand and help you scale your business by spreading the word.&lt;/p&gt;

&lt;p&gt;Remember, the community that you create around your business can bolster your foundation so that you have even more strength and leverage as you grow. Having a solid network is so important it’s part of the definition of scaling a business. So take the time to really build the “team” that will propel you into the future.&lt;/p&gt;

&lt;h3&gt;
  
  
  6. LEARN WHEN TO DELEGATE
&lt;/h3&gt;

&lt;p&gt;If you’ve built a strong team, you should have enough trust in them to delegate many important tasks so you can work “on” the business instead of “in” it. However, as a business owner, you want to feel like you’re involved in every aspect of your company and will sometimes have a hard time letting go in certain areas. To really learn how to scale a business, you must delegate tasks to those on your team. What are you doing that someone else could handle?&lt;/p&gt;

&lt;p&gt;Don’t trade your time for dollars. Your business has to be able to run itself and thrive even when you’re not there. Do this by addressing limiting beliefs such as “If I want something done right, I have to do it myself” and by establishing delegation habits that allow you to own your time.&lt;/p&gt;

&lt;h3&gt;
  
  
  7. BUILD YOUR BRAND
&lt;/h3&gt;

&lt;p&gt;Scaling a business requires learning who you are as a company and what you offer your customers. How do you compare to the competition? What do you have that no one else does? What are your biggest weaknesses? What makes you so powerful? What is your message? How do you disrupt your industry?&lt;/p&gt;

&lt;p&gt;It could take years to answer these questions, but you can at least start with a basic framework and build from there. Smaller businesses have the benefit of being able to shift gears more readily than larger corporations. So if there is a need for a new approach, use that as an opportunity to innovate and adapt.&lt;/p&gt;

&lt;p&gt;Remember, your brand will also set the tone for your company’s culture as you scale your business. It will set the standard for how you make your hires and will help you establish the kind of client experience you want. It will impact marketing, sales and design efforts, and it will influence the kind of company you ultimately become.&lt;/p&gt;

&lt;h3&gt;
  
  
  8. CONNECT WITH YOUR CUSTOMER
&lt;/h3&gt;

&lt;p&gt;What is scaling in business able to accomplish if it doesn’t also produce loyal customers? Not much. Creating raving fans of your product is critical for your business to thrive amid the ebb and flow of ever-changing consumer preferences. When you’re scaling a business, you’re in an incubation period where there’s room to test approaches to building and maintaining client relationships. This is the time to build client-centered practices into every facet of your business. You want every member of your team to demonstrate empathy, respect and open-mindedness internally so that a collaborative culture of innovation emerges. From there, everyone on staff is able to build rapport with your client, creating connections that will help your product sell itself. &lt;/p&gt;

&lt;h3&gt;
  
  
  9. WORK ON YOUR NETWORKING SKILLS
&lt;/h3&gt;

&lt;p&gt;“No man is an island,” and this is even more true in the case of entrepreneurs who are scaling a business. You must develop and cultivate a vast network of colleagues, business coaches, resources and mentors who can connect you to the right people and ensure you continue to grow. Attend regular business networking functions in your city or join an industry-related group that offers continuing education and connections to other professionals. Get involved in personal or business coaching and reach out to those who have been in business longer than you to see if they are willing to connect and possibly become your mentor. Scaling a business is not a solitary task. The more people you have on your side, the more successful you will be.&lt;/p&gt;

&lt;h3&gt;
  
  
  10. PRIORITIZE SUSTAINABILITY
&lt;/h3&gt;

&lt;p&gt;As important as creativity is for any company, running a business is not the place for knee-jerk decisions. Rather than thinking of creativity as a free-for-all tool for solving problems, think of it as a tool for scaling a business. When you prioritize mindful, sustainable growth, you learn to approach challenges thoughtfully so that the solutions you find support your company’s long-term well-being.  &lt;/p&gt;

&lt;h3&gt;
  
  
  11. CONTINUE ADAPTING AND INNOVATING
&lt;/h3&gt;

&lt;p&gt;Scaling a business may seem impossible if you’ve hit a plateau. The truth is, learning how to scale a business is never impossible, but you may need to change what you’re doing if you want to scale successfully. When was the last time your business focused on innovation? When did you last assess what’s holding your company back and tackle those barriers head-on? In business – and in life – if you’re not growing, you’re dying. Don’t change your company just for the sake of change – when you  strategically align your choices with your ultimate purpose, scaling your business will come easily. Take the time and do it right. Adopt a winning mindset, but be mindful as you do so. Remember that massive growth is one thing, but it’s sustainable growth that makes for a lasting company.&lt;/p&gt;

</description>
      <category>startup</category>
    </item>
    <item>
      <title>The first JavaScript conference in Ireland is back!</title>
      <dc:creator>Remo H. Jansen</dc:creator>
      <pubDate>Tue, 28 Jun 2022 14:36:18 +0000</pubDate>
      <link>https://dev.to/wolksoftware/the-first-javascript-conference-in-ireland-is-back-1k0i</link>
      <guid>https://dev.to/wolksoftware/the-first-javascript-conference-in-ireland-is-back-1k0i</guid>
      <description>&lt;h1&gt;
  
  
  JSDayIE is back on September 26th 2023
&lt;/h1&gt;

&lt;p&gt;We are very excited to introduce the second edition of the very first JavaScript conference in Ireland.&lt;/p&gt;

&lt;p&gt;JSDayIE 2023 is going to be a day dedicated to the JavaScript community in Ireland. After the COVID pandemic, the goal of the event is to bring together the JavaScript community for one day and showcase some of the best and most innovative work done by the members of the JavaScript community. &lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/-fpvYWMBixY"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;JSDayIE 2023 will take place on &lt;strong&gt;September 26th, 2023&lt;/strong&gt; at The Round Room at the Mansion House in Dawson Street, right in the heart of Dublin.&lt;/p&gt;

&lt;p&gt;JSDayIE is a single-track 1-day tech conference featuring talks from a diverse range of JavaScript-related technical topics. The talks will focus on JavaScript best practices, lessons learned, front-end JavaScript frameworks and libraries like React, Vue, and Angular, Node.js and GraphQL development, JavaScript performance, JavaScript flavours such as TypeScript or Reason ML and emerging technologies such as Web Assembly and Progressive Web Apps.&lt;/p&gt;

&lt;p&gt;We are working together with the JavaScript communities in Ireland such as Node.js Dublin, React Dublin, CorkJS, BelfastJS, DublinJS, Dublin TypeScript and many others to ensure that everybody is represented in this event. &lt;/p&gt;

&lt;p&gt;We are also taking an active part in promoting inclusivity and openness, not only at our conference but in the design and tech scene overall. We’re working together with communities such as Woman Who Code towards having a diverse lineup of speakers.&lt;/p&gt;

&lt;h2&gt;
  
  
  Tickets are now available!
&lt;/h2&gt;

&lt;p&gt;This year we are introducing a new remote ticket so everyone can watch the conference from home. We are very excited to share that you can &lt;a href="https://www.jsday.ie/tickets" rel="noopener noreferrer"&gt;get your remote or in-person ticket now!&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Call for Proposals now open!
&lt;/h2&gt;

&lt;p&gt;We are currently looking for speakers. If you want to give a talk, please visit the &lt;a href="https://www.jsday.ie/call-for-proposals-details" rel="noopener noreferrer"&gt;call for proposals page&lt;/a&gt; to learn how to submit your proposal now!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.jsday.ie%2F%2Fmedia%2Fgallery%2F2019%2FDSCN5744.jpg%3Fimwidth%3D1080" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.jsday.ie%2F%2Fmedia%2Fgallery%2F2019%2FDSCN5744.jpg%3Fimwidth%3D1080" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Sponsoring packages now available!
&lt;/h2&gt;

&lt;p&gt;We are also currently looking for sponsors. Sponsoring JSDayIE is a great way to contribute to the healthy growth of the JavaScript community in Ireland and offers a unique opportunity to expose your brand and find talent specialised in JavaScript technologies in Ireland. If you would like your company to sponsor JSDayIE 2023, please visit the &lt;a href="https://www.jsday.ie/sponsors" rel="noopener noreferrer"&gt;sponsors page&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Subscribe to one of our channels to be notified about future editions and important updates!&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.jsday.ie/newsletter/" rel="noopener noreferrer"&gt;Newsletter&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://twitter.com/JSDayIE" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.facebook.com/Jsdayie-336263463661254" rel="noopener noreferrer"&gt;Facebook&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.linkedin.com/company/jsdayie" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.youtube.com/channel/UC6CFGCJjA9GsOwZehQjfarQ" rel="noopener noreferrer"&gt;Youtube&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.instagram.com/jsdayie/" rel="noopener noreferrer"&gt;Instagram&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>conference</category>
      <category>javascript</category>
      <category>webdev</category>
      <category>frontend</category>
    </item>
    <item>
      <title>Implementing a low code customer support solution powered by Zendesk and Azure Logic Apps</title>
      <dc:creator>Remo H. Jansen</dc:creator>
      <pubDate>Mon, 09 Nov 2020 10:04:17 +0000</pubDate>
      <link>https://dev.to/wolksoftware/implementing-a-low-code-customer-support-solution-powered-by-zendesk-and-azure-logic-apps-52dn</link>
      <guid>https://dev.to/wolksoftware/implementing-a-low-code-customer-support-solution-powered-by-zendesk-and-azure-logic-apps-52dn</guid>
      <description>&lt;p&gt;In this post, we are going to learn how to implement customer support capabilities using a minimal code approach and relying on third party services. There are a lot of situations in which you might need to implement some customer support capabilities. Maybe you are developing your own product, or maybe you are working for a company that needs to improve their operations. &lt;/p&gt;

&lt;p&gt;With the arrival of COVID-19, e-commerce has become a major concern for most businesses. Having a good customer support strategy in place is a must these days. Online consumers demand features like online live chat or multi-channel communication and expect high responsiveness from online businesses.&lt;/p&gt;

&lt;p&gt;The pandemic has generated unprecedented levels of uncertainty for business and they need to be able to adapt in the shortest time possible. For this reason, we are going to really on third party services and use a minimal code approach. This allows us to dramatically reduce the time to market and development cost. Operational cost is also highly flexible because both Zendesk and Azure can adapt their offerings and prices to our business scale and needs.&lt;/p&gt;

&lt;h1&gt;
  
  
  Zendesk
&lt;/h1&gt;

&lt;p&gt;The first thing we are going to do is to visit &lt;a href="https://www.zendesk.com/" rel="noopener noreferrer"&gt;https://www.zendesk.com/&lt;/a&gt; and create an account. I will not document how to do this because Zendesk is very intuitive and it has very good documentation.&lt;/p&gt;

&lt;p&gt;After creating the account, you can visit the settings page and visit the channels section to find out your support email:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fqwcwax8eevqg86vn85s4.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fqwcwax8eevqg86vn85s4.jpg" alt="Zendesk support email" width="800" height="411"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The format of this email address should be &lt;code&gt;support@yourcompany.zendesk.com&lt;/code&gt;. You will need to remember this address because we are going to need it later.&lt;/p&gt;

&lt;p&gt;We can then visit the widget section under the channels section to enable the contact form and the web chat features:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fm8arwdul7dli64l9g66b.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fm8arwdul7dli64l9g66b.jpg" alt="Zendesk support widgets" width="800" height="494"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you visit the settings you will be able to find the installation guide:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fhqksfgyk2iiumn8bo0rh.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fhqksfgyk2iiumn8bo0rh.jpg" alt="Chat settings" width="800" height="490"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;All you need to do is to add a script tag to your website's source code:&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="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;script&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;ze-snippet&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="nx"&gt;src&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://static.zdassets.com/ekr/snippet.js?key=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/script&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We have enabled the contact form widget which is displayed when there are no customer support agents online:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fl8xi1tqv8m9h8fkkqjuu.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fl8xi1tqv8m9h8fkkqjuu.jpg" alt="Contact form" width="548" height="819"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We have also enabled the live chat widget which is displayed when customer support agents are online:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fxunf6vpm4hrrtpiq69ua.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fxunf6vpm4hrrtpiq69ua.jpg" alt="Live chat" width="536" height="801"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A little icon will be then displayed on the bottom right of your webpage. When a user clicks on the icon, the contact form or the live chat form will be displayed.&lt;/p&gt;

&lt;p&gt;Ideally, we want to have a single point to manage all our customer request. The request may have originated in our website, our email or social media:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Web: We are now ready to manage requests that originated on our website. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Email: Managing email requests can be achieved by enabling email forwarding from one of your company email addresses to your Zendesk email address.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Social media: You can visit the channel settings in Zendesk to connect your social media accounts with Zendesk.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Phone calls. Zendesk also allows you to manage phone calls as customer requests tickets. You can learn more using the Zendesk documentation.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Azure Logic Apps
&lt;/h1&gt;

&lt;p&gt;In most cases, the default Zendesk implementation would be enough to get started. However, in my case, I needed an additional custom contact form:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Ff12lhty1z04k08zyd5fs.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Ff12lhty1z04k08zyd5fs.jpg" alt="React web form" width="800" height="958"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I needed this form to be highly visible and the bottom right "help" button didn't have enough visibility for me. The webform was implemented using React and Formik.&lt;/p&gt;

&lt;p&gt;I wanted to send the request that originated using this form to Zendesk. The easiest solution would be to send an email to the Zendesk support email address. We need to implement an HTTP POST endpoint that takes the form details as JSON and send an email to the Zendesk support email address. I wanted to implement this with as little code as possible and the first thing that came so my mind was to use an Azure function.&lt;/p&gt;

&lt;p&gt;Using an Azure function would require us to define an HTTP trigger and the code that sends the email. We would need to manage the permissions so our email server allows us to send an email. This wasn't a massive job but it required me to save the code in a repository, deploy it, etc. It was too much work for something so simple. I wanted to find a better way and that is how I ended up using Azure Logic Apps.&lt;/p&gt;

&lt;p&gt;We can visit the Azure portal and create a new Azure Logic App, then use the designer to create the logic rules of our app. The first thing that we need to do is to define an HTTP trigger for our HTTP POST request:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fdsobb0e3ywwe7h497e59.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fdsobb0e3ywwe7h497e59.jpg" alt="Logig App incoming HTTP request" width="800" height="462"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can paste an example of the body of your request and the Logic App designer will automatically translate it into the request schema.&lt;/p&gt;

&lt;p&gt;When you save your logic, Azure will generate an URL that you can invoke from your app.&lt;/p&gt;

&lt;p&gt;The second thing that we need to do is to add a step: &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fe1d0fjcqqa6gmdp37nht.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fe1d0fjcqqa6gmdp37nht.jpg" alt="Login App adding a new step" width="800" height="316"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We need to add a step that will return an HTTP response:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fh1yowdmohefu28kt55mm.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fh1yowdmohefu28kt55mm.jpg" alt="Logic App send response step" width="800" height="440"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We then need to add a parallel step to send an email. In my case I use Gmail but there are other integrations available.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fi11z3rhy38jdfango79x.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fi11z3rhy38jdfango79x.jpg" alt="Logic App send email step" width="800" height="441"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We need to extract the data from the original HTTP request to add it to the email contents. We can do this using an expression:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F48xdwuafqf0b65ui36ca.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F48xdwuafqf0b65ui36ca.jpg" alt="Logic App using expressions" width="800" height="440"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We can use &lt;code&gt;triggerBody()&lt;/code&gt; to access the request body and &lt;code&gt;json(triggerBody())&lt;/code&gt; to transform it into JSON. We can then access the properties in the request body as follows &lt;code&gt;json(triggerBody()).company&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;We can then save everything and two resources should have been created:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fqyg2aach2smieldtx8as.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fqyg2aach2smieldtx8as.jpg" alt="Azure resource group" width="800" height="252"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We can then invoke the HTTP trigger in our logic app by sending an HTTP request from the web app:&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;const&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`INSERT_THE_TRIGGER_URL_HERE`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;method&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;POST&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;values&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;json&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can then use the browser developer tools to see if the request was successful:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F8wf4hywumvt6g8cijfz2.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F8wf4hywumvt6g8cijfz2.jpg" alt="Dev Tools HTTP request" width="800" height="340"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And finally, head to the Azure Logic App monitoring section to see if all the steps worked as expected. The monitoring tools with providing you with some details if something fails: &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fy3uef9z7owtfx4jlxba5.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fy3uef9z7owtfx4jlxba5.jpg" alt="Logic App monitoring" width="800" height="439"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If everything worked you should now have a new ticket in your Zendesk customer support dashboard:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F3y2rji4kzw4nv1ajajav.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F3y2rji4kzw4nv1ajajav.jpg" alt="Alt Text" width="800" height="238"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The operational cost of running this logic app is almost zero and we can get started with Zendesk for just $60 a year. We can now deliver a professional customer support experience on a budget and in just a few hours!&lt;/p&gt;

&lt;p&gt;As we can see Azure Logic apps can help us to solve real-business needs with almost no code. This allows us to move faster and adapt faster in a time of unprecedented uncertainty.&lt;/p&gt;

</description>
      <category>zendesk</category>
      <category>azure</category>
      <category>lowcode</category>
    </item>
    <item>
      <title>Automated refactoring for TypeScript apps with Tsmod</title>
      <dc:creator>Remo H. Jansen</dc:creator>
      <pubDate>Mon, 30 Sep 2019 12:29:54 +0000</pubDate>
      <link>https://dev.to/wolksoftware/automated-refactoring-for-typescript-apps-with-tsmod-4kko</link>
      <guid>https://dev.to/wolksoftware/automated-refactoring-for-typescript-apps-with-tsmod-4kko</guid>
      <description>&lt;p&gt;Inspired by the talk from &lt;a href="https://hmh.engineering/automating-javascript-refactoring-2f0a123702e8" rel="noopener noreferrer"&gt;Cristina Bernardis&lt;/a&gt; about &lt;a href="https://github.com/facebook/jscodeshift" rel="noopener noreferrer"&gt;jscodeshift&lt;/a&gt; at &lt;a href="https://www.jsday.org/" rel="noopener noreferrer"&gt;JSDayIE&lt;/a&gt; I have released &lt;a href="https://github.com/WolkSoftware/tsmod" rel="noopener noreferrer"&gt;Tsmod&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2F0qxpoa0bvrnzs01ihs7f.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2F0qxpoa0bvrnzs01ihs7f.png" alt="Alt Text" width="800" height="511"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A library that allows us to write automated refactoring code modifications powered by &lt;a href="https://twitter.com/DavidSherret" rel="noopener noreferrer"&gt;David Sherret&lt;/a&gt;'s &lt;a href="https://github.com/dsherret/ts-morph" rel="noopener noreferrer"&gt;ts-morph&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is this about?
&lt;/h2&gt;

&lt;p&gt;If you have a very large codebase and you want to change something across many files this tool will allow you to write a script that will do the work for you. This is a good idea because it can save you time but also because it can be used by other members of the team as a valuable source of information. The transform scripts can also be shared online as open source. A common example is a migration script for a breaking change in the API of a framework. You can release the new version of the framework together with the transform scripts to help the users of the framework to upgrade their version with ease.&lt;/p&gt;

&lt;h2&gt;
  
  
  Installation
&lt;/h2&gt;

&lt;p&gt;You can install this module as a global dependency using npm:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm install -g tsmod
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Please note that if you have never used TypeScript or ts-node you will also need them:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm install -g typescript ts-node
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The typescript module is the TypeScript compiler and the ts-node module is a version of Node.js that can work directly with TypeScript files (&lt;code&gt;.ts&lt;/code&gt;) instead of using JavaScript files (&lt;code&gt;.js&lt;/code&gt;). &lt;/p&gt;

&lt;h2&gt;
  
  
  Usage
&lt;/h2&gt;

&lt;p&gt;The following command applies the transform &lt;code&gt;var_to_const_tramsform.ts&lt;/code&gt; to the files &lt;code&gt;fileA.ts&lt;/code&gt; and &lt;code&gt;fileB.ts&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;tsmod &lt;span class="nt"&gt;-t&lt;/span&gt; var_to_const_tramsform.ts fileA.ts fileB.ts
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Please Note&lt;/strong&gt;: A TypeScript compiler configuration file (&lt;code&gt;tsconfig.json&lt;/code&gt;) file is expected in the current directory when you run the previous command.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Transform example
&lt;/h2&gt;

&lt;p&gt;The transforms are powered by the &lt;code&gt;ts-morph&lt;/code&gt; API. You can learn more about the API at &lt;a href="https://ts-morph.com/manipulation/" rel="noopener noreferrer"&gt;https://ts-morph.com&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The following example changes all &lt;code&gt;var&lt;/code&gt; variable declarations into &lt;code&gt;const&lt;/code&gt; variable declarations:&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="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;SourceFile&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;SyntaxKind&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;VariableDeclarationKind&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;ts-morph&lt;/span&gt;&lt;span class="dl"&gt;"&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;varToConstTransform&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;file&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;SourceFile&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;transformArgs&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="c1"&gt;// Find all variable declarations in source file&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;variableStatements&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;file&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getDescendantsOfKind&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nx"&gt;SyntaxKind&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;VariableStatement&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="c1"&gt;// Change var for const for each statement&lt;/span&gt;
  &lt;span class="nx"&gt;variableStatements&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;variableStatement&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;declarationKind&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;variableStatement&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getDeclarationKind&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;declarationKind&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;VariableDeclarationKind&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Var&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;variableStatement&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setDeclarationKind&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;VariableDeclarationKind&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Const&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="c1"&gt;// Return source code&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;updatedSourceCode&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;file&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getText&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;updatedSourceCode&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;h2&gt;
  
  
  Options
&lt;/h2&gt;

&lt;p&gt;For additional help use the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;tsmod &lt;span class="nt"&gt;-h&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I hope you enjoyed it, please let me know your thoughts!&lt;/p&gt;

&lt;p&gt;Please note that at the moment this project is just an experiment is not considered a mature piece of software...&lt;/p&gt;

</description>
      <category>typescript</category>
      <category>javascript</category>
      <category>tooling</category>
    </item>
    <item>
      <title>5 JavaScript conferences to attend before the end of 2019</title>
      <dc:creator>Remo H. Jansen</dc:creator>
      <pubDate>Thu, 25 Jul 2019 14:06:50 +0000</pubDate>
      <link>https://dev.to/wolksoftware/5-javascript-conferences-to-attend-before-the-end-of-2019-7cg</link>
      <guid>https://dev.to/wolksoftware/5-javascript-conferences-to-attend-before-the-end-of-2019-7cg</guid>
      <description>&lt;p&gt;Now that many of us have finished our holidays and we are back in work we have started to plan how to stay up to date and up-skill for the rest of the year. Here are 5 conferences to attend before the end of 2019!&lt;/p&gt;

&lt;h2&gt;
  
  
  JSConf US (US, August)
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fe64soqjcl3iz5qrb8eqs.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fe64soqjcl3iz5qrb8eqs.png" width="268" height="188"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;JSConf US has pushed the JavaScript outside of its comfort zone, the web browser, and into the forefront of servers, drones, robots, and video games. &lt;/p&gt;

&lt;p&gt;The "Choose Your Own Adventure" day is what sets JSConf US apart from other conferences. It provides you with an extraordinary opportunity to socialize with the brightest minds in our community in a new and different environment. JSConf US has IoT workshops like NodeBots and NodeBoats for those that want to learn how to program the physical world and Surfing lessons or a trip to the San Diego Zoo Safari Park for those that want to step away from the computer and go outside!&lt;/p&gt;

&lt;p&gt;Early bird tickets start at 850 USD. You can learn more about this event and get your tickets at &lt;a href="https://2019.jsconf.us/" rel="noopener noreferrer"&gt;https://2019.jsconf.us/&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  JSDayIE (Ireland, September)
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Foq27rpareanuyikyy8jz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Foq27rpareanuyikyy8jz.png" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;JSDayIE 2019 is a 1-day single-track tech conference dedicated to the JavaScript community in Ireland featuring over 450 attendees and some of the best JavaScript professionals and organizations in Ireland.&lt;/p&gt;

&lt;p&gt;JSDayIE is the first JavaScript conference in Ireland and will take place in 2019, on September 20th at The Round Room at the Mansion House in Dawson Street, Dublin.&lt;/p&gt;

&lt;p&gt;The Dev.to community members can access a 15% discount &lt;a href="https://ti.to/wolk-software-limited/jsdayie-2019/discount/Dev" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Early bird tickets start at 116 EUR. You can learn more about this event and get your tickets at &lt;a href="https://www.jsday.org/" rel="noopener noreferrer"&gt;https://www.jsday.org/&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  TsConf (US, October)
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fkjo3q6z78xadylc6situ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fkjo3q6z78xadylc6situ.png" width="800" height="420"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The first conference ever focused completely on TypeScript! Beyond the typical introduction to TypeScript talk, at TsConf you will spend the day discussing best practices and advanced features of the language, including information from key members of the TypeScript team. All in an informal and fun environment!&lt;/p&gt;

&lt;p&gt;Last year’s TSconf speaker line-up rocked. Introductory topics take a backseat at this conference where we put expert JavaScript engineers at the wheel to steer us deep into the land of TypeScript.&lt;/p&gt;

&lt;p&gt;Early bird tickets start at 350 USD. You can learn more about this event and get your tickets at &lt;a href="https://tsconf.io/" rel="noopener noreferrer"&gt;https://tsconf.io/&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  NodeConf EU (Ireland, November)
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fnx5gv18corzqb2943pm4.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fnx5gv18corzqb2943pm4.jpg" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;NodeConf EU is the key Node.js event in Europe, providing a forum for the Node.js community, the conference has become legendary in the Node community for all the right reasons. Over the course of a few days each year, some of the key people in Node join together in Ireland at the conference to celebrate Node. It's a place where you will find some of the best speakers and experts on the subject of Node, Discussions about collaboration, and about becoming contributors to the Node product.&lt;/p&gt;

&lt;p&gt;Early bird tickets start at 799 EUR. You can learn more about this event and get your tickets at &lt;a href="https://www.nodeconf.eu/" rel="noopener noreferrer"&gt;https://www.nodeconf.eu/&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  DotJS (Paris, December)
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fynocz242z9x1bkb0u18c.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fynocz242z9x1bkb0u18c.jpg" width="800" height="453"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;DotJS is coming back in 2019 and for the first time, it will be a 2-day conference! &lt;/p&gt;

&lt;p&gt;Day 1 will be all about Frontend development (UI frameworks, browsers, ...). Day 2 will be about Backend development and JavaScript as a language (Node.js, ES2019, compilers, ...).&lt;/p&gt;

&lt;p&gt;DotJS 2019 will continue inviting the best and brightest hackers in the community to explore new horizons. You can expect a few surprises &amp;amp; more than 1400 new friends to make!&lt;/p&gt;

&lt;p&gt;Early bird tickets start at 499 EUR. You can learn more about this event and get your tickets at &lt;a href="https://www.dotjs.io/" rel="noopener noreferrer"&gt;https://www.dotjs.io/&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>conferences</category>
      <category>events</category>
    </item>
    <item>
      <title>JSDayIE 2019 CFP now open!</title>
      <dc:creator>Remo H. Jansen</dc:creator>
      <pubDate>Fri, 01 Mar 2019 10:03:25 +0000</pubDate>
      <link>https://dev.to/wolksoftware/jsdayie-2019-cfp-now-open-1b0m</link>
      <guid>https://dev.to/wolksoftware/jsdayie-2019-cfp-now-open-1b0m</guid>
      <description>&lt;p&gt;The JSDayIE 2019 CFP is now open! We’re excited to welcome the JavaScript community to submit talks for JSDayIE 2019 that will take place on September 20th 2019. The Call for Proposals closes on April 15th, 2019.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://svbtleusercontent.com/kHgRtcaKb5uFpoeBjN78nC0xspap.png" rel="noopener noreferrer"&gt;&lt;img src="https://media2.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%2Fnqds1sddpzg18m95oqys.png" alt="blog_post_2.png" width="700" height="350"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We are looking for a multitude of topics and perspectives but most of all we value:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Original topics&lt;/strong&gt;, presented for the first time&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Practical ideas&lt;/strong&gt; that attendees can apply at work the next day&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Trends and hot topics&lt;/strong&gt; which are relevant in 2019 and beyond&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fresh perspectives&lt;/strong&gt; on the JS ecosystem&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We don't have a specific theme for JSDayIE. Instead, we’re aiming to select talks that are interesting for as many JavaScript developers as possible. Our audience skill level is intermediate to advanced.&lt;/p&gt;

&lt;p&gt;All talks should be in English and 25 minutes long. We will be on a tight schedule and will enforce the time limits rigorously. We suggest that you time your presentation accordingly in advance.&lt;/p&gt;

&lt;h2&gt;
  
  
  We can help
&lt;/h2&gt;

&lt;p&gt;Not everyone is a natural-born talent on stage. Not everyone can produce kick-ass slide decks. Not everyone is a live-demo master. Not everyone knows they have something great to talk about.&lt;/p&gt;

&lt;p&gt;There are about a million reasons why you may not consider yourself a speaker. We are here to prove you wrong. If all you have is a gut feeling that you should be on stage, we are here to help you develop or hone the skills you think you lack to deliver a great presentation.&lt;/p&gt;

&lt;p&gt;We are committed to fulfilling our mission as a community event. We are all community people and we want to be as close to you as possible. We will try to be supportive and helpful and we will do our best to get back to you with valuable feedback from the CFP process. In case you wish to talk with someone from the team, do not hesitate to write an email at &lt;a href="mailto:hello@jsday.org"&gt;hello@jsday.org&lt;/a&gt; (just please don’t use this email to submit a proposal).&lt;/p&gt;

&lt;p&gt;Please visit the &lt;a href="https://www.jsday.org/cfp_details" rel="noopener noreferrer"&gt;official CFP guidelines page&lt;/a&gt; if you need additional help.&lt;/p&gt;

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

</description>
    </item>
    <item>
      <title>Introducing JSDayIE 2019!</title>
      <dc:creator>Remo H. Jansen</dc:creator>
      <pubDate>Fri, 01 Mar 2019 09:51:00 +0000</pubDate>
      <link>https://dev.to/wolksoftware/introducing-jsdayie-2019--515p</link>
      <guid>https://dev.to/wolksoftware/introducing-jsdayie-2019--515p</guid>
      <description>&lt;p&gt;Welcome to the official announcement of JSDayIE 2019! We are very excited to introduce the very first JavaScript conference in Ireland.&lt;/p&gt;

&lt;p&gt;JSDayIE 2019 is going to be a day dedicated to the JavaScript community in Ireland with over 450 attendees. The goal of the event is to bring together the JavaScript community for one day and showcase some of the best and most innovative work done by the members of the JavaScript community in Ireland.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fqxay8dac91t9vthgepez.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fqxay8dac91t9vthgepez.png" width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;JSDayIE is presented by &lt;a href="http://www.wolksoftware.com/" rel="noopener noreferrer"&gt;Wolk Software&lt;/a&gt;. Wolk Software is an Ireland based startup dedicated to empowering developers and teams to achieve their best through consultancy and training services and technical publications and events.&lt;/p&gt;

&lt;p&gt;JSDayIE 2019 will take place on September 20th, 2019 at The Round Room at the Mansion House in Dawson Street, right in the heart of Dublin.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2F5uug76omf6wyhnqj5h4s.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2F5uug76omf6wyhnqj5h4s.png" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;JSDayIE is a single-track 1-day tech conference featuring talks from a diverse range of JavaScript-related technical topics. The talks will focus on JavaScript best practices, lessons learned, front-end JavaScript frameworks and libraries like React, Vue, and Angular, Node.js and GraphQL development, JavaScript performance, JavaScript flavours such as TypeScript or Reason ML and emerging technologies such as Web Assembly and Progressive Web Apps.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fx836jgqagsdu6xe73zcw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fx836jgqagsdu6xe73zcw.png" width="800" height="480"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We are working together with the JavaScript communities in Ireland such as Node.js Dublin, React Dublin, CorkJS, BelfastJS, DublinJS, Dublin TypeScript and many others to ensure that everybody is represented in this event.&lt;/p&gt;

&lt;p&gt;We are also taking an active part in promoting inclusivity and openness, not only at our conference but in the design and tech scene overall. We’re working together with communities such as Woman Who Code towards having a diverse lineup of speakers.&lt;/p&gt;

&lt;p&gt;We are currently looking for speakers. If you want to give a talk, Please visit the &lt;a href="https://www.jsday.org/cfp" rel="noopener noreferrer"&gt;call for proposals page&lt;/a&gt; to learn how to submit your proposal now!&lt;/p&gt;

&lt;p&gt;We are also currently looking for sponsors. Sponsoring JSDayIE is a great way to contribute to the healthy growth of the JavaScript community in Ireland and offers a unique opportunity to expose your brand and find talent specialized in JavaScript technologies in Ireland. If you would like your company to sponsor JSDayIE 2019, please visit the &lt;a href="https://www.jsday.org/sponsors" rel="noopener noreferrer"&gt;sponsors page&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The tickets will be available very soon! Subscribe to our &lt;a href="https://www.jsday.org/newsletter" rel="noopener noreferrer"&gt;Newsletter&lt;/a&gt; or follow us on &lt;a href="https://twitter.com/JSDayIE" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt;, &lt;a href="https://www.facebook.com/Jsdayie-336263463661254" rel="noopener noreferrer"&gt;Facebook&lt;/a&gt; or &lt;a href="https://www.linkedin.com/company/jsdayie/" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt; to be notified when the tickets become available and other important updates!&lt;/p&gt;

&lt;p&gt;Logo credits: The JSDayIE 2019 logo is based on the Dublin logo design by &lt;a href="https://twitter.com/KSheehan77" rel="noopener noreferrer"&gt;Kieran Sheehan&lt;/a&gt; and it is licensed under the Creative Commons Attribution-NoDerivatives license.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>conferences</category>
      <category>community</category>
    </item>
    <item>
      <title>Why TypeScript is a better option than JavaScript when it comes to functional programming?</title>
      <dc:creator>Remo H. Jansen</dc:creator>
      <pubDate>Wed, 30 Jan 2019 15:47:10 +0000</pubDate>
      <link>https://dev.to/wolksoftware/why-typescript-is-a-better-option-than-javascript-when-it-comes-to-functional-programming-3mp0</link>
      <guid>https://dev.to/wolksoftware/why-typescript-is-a-better-option-than-javascript-when-it-comes-to-functional-programming-3mp0</guid>
      <description>&lt;p&gt;In this post, I would like to discuss the importance of static types in functional programming languages and why TypeScript is a better option than JavaScript when it comes to functional programming due to the lack of a static type system in JavaScript.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fgmmmx4nebcdw15qvsghb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fgmmmx4nebcdw15qvsghb.png" alt="drawing" width="800" height="827"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Life without types in a functional programming code base
&lt;/h2&gt;

&lt;p&gt;Please try to put your mind on a hypothetical situation so we can showcase the value of static types. Let's imagine that you are writing some code for an elections-related application. You just joined the team, and the application is quite big. You need to write a new feature, and one of the requirements is to ensure that the user of the application is eligible to vote in the elections. One of the older members of the team has pointed out to us that some of the code that we need is already implemented in a module named &lt;code&gt;@domain/elections&lt;/code&gt; and that we can import it as follows:&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="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;isEligibleToVote&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;@domain/elections&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 import is a great starting point, and We feel grateful for the help provided by or workmate. It is time to get some work done. However, we have a problem. We don't know how to use &lt;code&gt;isEligibleToVote&lt;/code&gt;. If we try to guess the type of &lt;code&gt;isEligibleToVote&lt;/code&gt; by its name, we could assume that it is most likely a function, but we don't know what arguments should be provided to it:&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="nf"&gt;isEligibleToVote&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;????&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We are not afraid about reading someoneelses code do we open the source code of the source code of the &lt;code&gt;@domain/elections&lt;/code&gt; module and we encounter the following:&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;const&lt;/span&gt; &lt;span class="nx"&gt;either&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;f&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;g&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;arg&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;f&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;arg&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nf"&gt;g&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;arg&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;both&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;f&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;g&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;arg&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;f&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;arg&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nf"&gt;g&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;arg&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;OUR_COUNTRY&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Ireland&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;wasBornInCountry&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;person&lt;/span&gt; &lt;span class="o"&gt;=&amp;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;birthCountry&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;OUR_COUNTRY&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;wasNaturalized&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;person&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nc"&gt;Boolean&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;naturalizationDate&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;isOver18&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;person&lt;/span&gt; &lt;span class="o"&gt;=&amp;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;age&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="mi"&gt;18&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;isCitizen&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;either&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;wasBornInCountry&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;wasNaturalized&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;isEligibleToVote&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;both&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;isOver18&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;isCitizen&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The preceding code snippet uses a functional programming style. The &lt;code&gt;isEligibleToVote&lt;/code&gt; performs a series of checks:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The person must be over 10&lt;/li&gt;
&lt;li&gt;The person must be a citizen&lt;/li&gt;
&lt;li&gt;To be a citizen, the person must be born in the country or naturalized&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We need to start doing some reverse engineering in our brain to be able to decode the preceding code. I was almost sure that &lt;code&gt;isEligibleToVote&lt;/code&gt; is a function, but now I have some doubts because I don't see the &lt;code&gt;function&lt;/code&gt; keyword or arrow functions (&lt;code&gt;=&amp;gt;&lt;/code&gt;) in its declaration:&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;const&lt;/span&gt; &lt;span class="nx"&gt;isEligibleToVote&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;both&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;isOver18&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;isCitizen&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;TO be able to know what is it we need to examine what is the &lt;code&gt;both&lt;/code&gt; function doing. I can see that both takes two arguments &lt;code&gt;f&lt;/code&gt; and &lt;code&gt;g&lt;/code&gt; and I can see that they are function because they are invoked &lt;code&gt;f(arg)&lt;/code&gt; and &lt;code&gt;g(arg)&lt;/code&gt;. The &lt;code&gt;both&lt;/code&gt; function returns a function &lt;code&gt;arg =&amp;gt; f(arg) &amp;amp;&amp;amp; g(arg)&lt;/code&gt; that takes an argument named &lt;code&gt;args&lt;/code&gt; and its shape is totally unknown for us at this point:&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;const&lt;/span&gt; &lt;span class="nx"&gt;both&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;f&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;g&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;arg&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;f&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;arg&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nf"&gt;g&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;arg&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we can return to the &lt;code&gt;isEligibleToVote&lt;/code&gt; function and try to examine again to see if we can find something new. We now know that &lt;code&gt;isEligibleToVote&lt;/code&gt; is the function returned by the &lt;code&gt;both&lt;/code&gt; function &lt;code&gt;arg =&amp;gt; f(arg) &amp;amp;&amp;amp; g(arg)&lt;/code&gt; and we also know that &lt;code&gt;f&lt;/code&gt; is &lt;code&gt;isOver18&lt;/code&gt; and &lt;code&gt;g&lt;/code&gt; is &lt;code&gt;isCitizen&lt;/code&gt; so &lt;code&gt;isEligibleToVote&lt;/code&gt; is doing something similar to the following:&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;const&lt;/span&gt; &lt;span class="nx"&gt;isEligibleToVote&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;arg&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;isOver18&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;arg&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nf"&gt;isCitizen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;arg&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We still need to find out what is the argument &lt;code&gt;arg&lt;/code&gt;. We can examine the &lt;code&gt;isOver18&lt;/code&gt; and &lt;code&gt;isCitizen&lt;/code&gt; functions to find some details.&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;const&lt;/span&gt; &lt;span class="nx"&gt;isOver18&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;person&lt;/span&gt; &lt;span class="o"&gt;=&amp;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;age&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="mi"&gt;18&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This piece of information is instrumental. Now we know that &lt;code&gt;isOver18&lt;/code&gt; expects an argument named &lt;code&gt;person&lt;/code&gt; and that it is an object with a property named &lt;code&gt;age&lt;/code&gt; we can also guess by the comparison &lt;code&gt;person.age &amp;gt;= 18&lt;/code&gt; that &lt;code&gt;age&lt;/code&gt; is a number.&lt;/p&gt;

&lt;p&gt;Lets take a look to the &lt;code&gt;isCitizen&lt;/code&gt; function as well:&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;const&lt;/span&gt; &lt;span class="nx"&gt;isCitizen&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;either&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;wasBornInCountry&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;wasNaturalized&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;We our out of luck here and we need to examine the &lt;code&gt;either&lt;/code&gt;, &lt;code&gt;wasBornInCountry&lt;/code&gt; and &lt;code&gt;wasNaturalized&lt;/code&gt; functions:&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;const&lt;/span&gt; &lt;span class="nx"&gt;either&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;f&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;g&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;arg&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;f&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;arg&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nf"&gt;g&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;arg&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;OUR_COUNTRY&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Ireland&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;wasBornInCountry&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;person&lt;/span&gt; &lt;span class="o"&gt;=&amp;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;birthCountry&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;OUR_COUNTRY&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;wasNaturalized&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;person&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nc"&gt;Boolean&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;naturalizationDate&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Both the &lt;code&gt;wasBornInCountry&lt;/code&gt; and &lt;code&gt;wasNaturalized&lt;/code&gt; expect an argument named &lt;code&gt;person&lt;/code&gt; and now we have discovered new properties:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The &lt;code&gt;birthCountry&lt;/code&gt; property seems to be a string&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;naturalizationDate&lt;/code&gt; property seems to be date or null&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The &lt;code&gt;either&lt;/code&gt; function pass an argument to both &lt;code&gt;wasBornInCountry&lt;/code&gt; and &lt;code&gt;wasNaturalized&lt;/code&gt; which means that &lt;code&gt;arg&lt;/code&gt; must be a person. It took a lot of cognitive effort, and we feel tired but now we know that we can use the &lt;code&gt;isElegibleToVote&lt;/code&gt; function can be used as follows:&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="nf"&gt;isEligibleToVote&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;27&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;birthCountry&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Ireland&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;naturalizationDate&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We could overcome some of these problems using documentation such as JSDoc. However, that means more work and the documentation can get outdated quickly. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;TypeScript can help to validate our JSDoc annotations are up to date with our code base. However, if we are going to do that, why not adopt TypeScript in the first place?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Life with types in a functional programming code base
&lt;/h2&gt;

&lt;p&gt;Now that we know how difficult is to work in a functional programming code base without types we are going to take a look to how it feels like to work on a functional programming code base with static types. We are going to go back to the same starting point, we have joined a company, and one of our workmates has pointed us to the &lt;code&gt;@domain/elections&lt;/code&gt; module. However, this time we are in a parallel universe and the code base is statically typed.&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="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;isEligibleToVote&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;@domain/elections&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;We don't know if &lt;code&gt;isEligibleToVote&lt;/code&gt; is function. However, this time we can do much more than guessing. We can use our IDE to hover over the &lt;code&gt;isEligibleToVote&lt;/code&gt; variable to confirm that it is a function:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fi1mjt45mmnmr7su19v33.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fi1mjt45mmnmr7su19v33.png" width="800" height="210"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We can then try to invoke the &lt;code&gt;isEligibleToVote&lt;/code&gt; function, and our IDE will let us know that we need to pass an object of type &lt;code&gt;Person&lt;/code&gt; as an argument:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fa100jw16cz2ckine98w3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fa100jw16cz2ckine98w3.png" width="800" height="294"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If we try to pass an object literal our IDE will show as all the properties and of the &lt;code&gt;Person&lt;/code&gt; type together with their types:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fvly83tavqsyj06uwjbt8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fvly83tavqsyj06uwjbt8.png" width="800" height="380"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;That's it! No thinking or documentation required! All thanks to the TypeScript type system.&lt;/p&gt;

&lt;p&gt;The following code snippet contains the type-safe version of the &lt;code&gt;@domain/elections&lt;/code&gt; module:&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;Person&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;birthCountry&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;naturalizationDate&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Date&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kc"&gt;null&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;const&lt;/span&gt; &lt;span class="nx"&gt;either&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;T1&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;f&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;T1&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;boolean&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
   &lt;span class="nx"&gt;g&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;T1&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;boolean&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;arg&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;T1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;f&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;arg&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nf"&gt;g&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;arg&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;both&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;T1&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;f&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;T1&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;boolean&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
   &lt;span class="nx"&gt;g&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;T1&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;boolean&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;arg&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;T1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;f&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;arg&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nf"&gt;g&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;arg&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;OUR_COUNTRY&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Ireland&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;wasBornInCountry&lt;/span&gt; &lt;span class="o"&gt;=&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="o"&gt;=&amp;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;birthCountry&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;OUR_COUNTRY&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;wasNaturalized&lt;/span&gt; &lt;span class="o"&gt;=&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="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nc"&gt;Boolean&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;naturalizationDate&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;isOver18&lt;/span&gt; &lt;span class="o"&gt;=&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="o"&gt;=&amp;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;age&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="mi"&gt;18&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;isCitizen&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;either&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;wasBornInCountry&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;wasNaturalized&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;isEligibleToVote&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;both&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;isOver18&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;isCitizen&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Adding type annotations can take a little bit of additional type, but the benefits will undoubtedly pay off. Our code will be less prone to errors, it will be self-documented, and our team members will be much more productive because they will spend less time trying to understand the pre-existing code.&lt;/p&gt;

&lt;p&gt;The universal UX principle &lt;a href="https://amzn.to/2Ti3uhW" rel="noopener noreferrer"&gt;&lt;em&gt;Don't Make Me Think&lt;/em&gt;&lt;/a&gt; can also bring great improvements to our code. Remember that at the end of the day we spend much more time reading than writing code.&lt;/p&gt;

&lt;h2&gt;
  
  
  About types in functional programming languages
&lt;/h2&gt;

&lt;p&gt;Functional programming languages don't have to be statically typed. However, functional programming languages tend to be statically typed. According to Wikipedia, this tendency has been rinsing since the 1970s:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Since the development of Hindley–Milner type inference in the 1970s, functional programming languages have tended to use typed lambda calculus, rejecting all invalid programs at compilation time and risking false positive errors, as opposed to the untyped lambda calculus, that accepts all valid programs at compilation time and risks false negative errors, used in Lisp and its variants (such as Scheme), though they reject all invalid programs at runtime, when the information is enough to not reject valid programs. The use of algebraic datatypes makes manipulation of complex data structures convenient; &lt;strong&gt;the presence of strong compile-time type checking makes programs more reliable in absence of other reliability techniques&lt;/strong&gt; like test-driven development, while type inference frees the programmer from the need to manually declare types to the compiler in most cases.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Let's consider an object-oriented implementation of the &lt;code&gt;isEligibleToVote&lt;/code&gt; feature without types:&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;const&lt;/span&gt; &lt;span class="nx"&gt;OUR_COUNTRY&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Ireland&lt;/span&gt;&lt;span class="dl"&gt;"&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;class&lt;/span&gt; &lt;span class="nc"&gt;Person&lt;/span&gt; &lt;span class="p"&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;birthCountry&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;naturalizationDate&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&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;_birthCountry&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;birthCountry&lt;/span&gt;&lt;span class="p"&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;_age&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;age&lt;/span&gt;&lt;span class="p"&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;_naturalizationDate&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;naturalizationDate&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="nf"&gt;_wasBornInCountry&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="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;_birthCountry&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;OUR_COUNTRY&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="nf"&gt;_wasNaturalized&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="nc"&gt;Boolean&lt;/span&gt;&lt;span class="p"&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;_naturalizationDate&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="nf"&gt;_isOver18&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="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;_age&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="mi"&gt;18&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="nf"&gt;_isCitizen&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="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;_wasBornInCountry&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="nf"&gt;_wasNaturalized&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="nf"&gt;isEligibleToVote&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="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;_isOver18&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;_isCitizen&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Figuring this out how the preceding code should be invoked is not a trivial task:&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="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="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@domain/elections&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Person&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Ireland&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;27&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="nf"&gt;isEligibleToVote&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once more, without types, we are forced to take a look at the implementation details.&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="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;birthCountry&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;naturalizationDate&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&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;_birthCountry&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;birthCountry&lt;/span&gt;&lt;span class="p"&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;_age&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;age&lt;/span&gt;&lt;span class="p"&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;_naturalizationDate&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;naturalizationDate&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;When we use static types things become 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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;OUR_COUNTRY&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Ireland&lt;/span&gt;&lt;span class="dl"&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;Person&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="nx"&gt;_birthCountry&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="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="nx"&gt;_naturalizationDate&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Date&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;readonly&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="k"&gt;public&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;birthCountry&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;naturalizationDate&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Date&lt;/span&gt; &lt;span class="o"&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="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;_birthCountry&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;birthCountry&lt;/span&gt;&lt;span class="p"&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;_age&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;age&lt;/span&gt;&lt;span class="p"&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;_naturalizationDate&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;naturalizationDate&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nf"&gt;_wasBornInCountry&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="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;_birthCountry&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;OUR_COUNTRY&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nf"&gt;_wasNaturalized&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="nc"&gt;Boolean&lt;/span&gt;&lt;span class="p"&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;_naturalizationDate&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nf"&gt;_isOver18&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="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;_age&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="mi"&gt;18&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nf"&gt;_isCitizen&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="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;_wasBornInCountry&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="nf"&gt;_wasNaturalized&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;isEligibleToVote&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="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;_isOver18&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;_isCitizen&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The constructor tells us how many arguments are needed and the expected types of each of the arguments:&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;public&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;birthCountry&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;naturalizationDate&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Date&lt;/span&gt; &lt;span class="o"&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="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;_birthCountry&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;birthCountry&lt;/span&gt;&lt;span class="p"&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;_age&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;age&lt;/span&gt;&lt;span class="p"&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;_naturalizationDate&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;naturalizationDate&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;I personally think that functional programming is usually harder to reverse-engineering than object-oriented programming. Maybe this is due to my object-oriented background. However, whatever the reason I'm sure about one thing: Types really make my life easier, and their benefits are even more noticeable when I'm working on a functional programming code base.&lt;/p&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;Static types are a valuable source of information. Since we spend much more time reading code than writing code, we should optimize our workflow so we can be more efficient reading code rather than more efficient writing code. Types can help us to remove a great amount of cognitive effort so we can focus on the business problem that we are trying to solve.&lt;/p&gt;

&lt;p&gt;While all of this is true in object-oriented programming code bases the benefits are even more noticeable in functional programming code bases and this exactly why I like to argue that  TypeScript is a better option than JavaScript when it comes to functional programming. What do you think?&lt;/p&gt;

&lt;p&gt;If you have enjoyed this post and you are interested in Functional Programming or TypeScript, please check out my upcoming book &lt;a href="http://www.functionaltypescript.com/" rel="noopener noreferrer"&gt;&lt;strong&gt;&lt;em&gt;Hands-On Functional Programming with TypeScript&lt;/em&gt;&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fq6x86kh133aq3idf60mg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fq6x86kh133aq3idf60mg.png" width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>web</category>
      <category>javascript</category>
      <category>typescript</category>
    </item>
  </channel>
</rss>
