<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Chris927</title>
    <description>The latest articles on Forem by Chris927 (@chris927).</description>
    <link>https://forem.com/chris927</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F512870%2F49d6ecf3-e4d5-4cbe-92d0-d6589ef579dd.png</url>
      <title>Forem: Chris927</title>
      <link>https://forem.com/chris927</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/chris927"/>
    <language>en</language>
    <item>
      <title>Extending Express' Types with TypeScript Declaration Merging - TypeScript 4</title>
      <dc:creator>Chris927</dc:creator>
      <pubDate>Thu, 12 Nov 2020 12:20:43 +0000</pubDate>
      <link>https://forem.com/chris927/extending-express-types-with-typescript-declaration-merging-typescript-4-3jh</link>
      <guid>https://forem.com/chris927/extending-express-types-with-typescript-declaration-merging-typescript-4-3jh</guid>
      <description>&lt;p&gt;TypeScript is evolving fast (as are a lot of tools in the Open Source space, gladly!)... but this means that what worked in a previous version may not work the same any more in the next major release. This happened to me in this case with TypeScript 4 and declaration merging.&lt;/p&gt;

&lt;p&gt;There are good articles out there (like &lt;a href="https://dev.to/kwabenberko/extend-express-s-request-object-with-typescript-declaration-merging-1nn5"&gt;this one&lt;/a&gt;, thanks, &lt;a href="https://dev.to/kwabenberko"&gt;Kwabena&lt;/a&gt;!), but it's slightly different in TypeScript 4 (and with modern &lt;a href="https://github.com/typescript-eslint/typescript-eslint"&gt;typescript-eslint&lt;/a&gt; rules).&lt;/p&gt;

&lt;p&gt;Sounds like your issue? Read on (or jump straight to the code example below).&lt;/p&gt;

&lt;p&gt;To keep it simple, let's imagine we have some middleware (e.g. &lt;a href="http://www.passportjs.org/"&gt;passport&lt;/a&gt;) that makes the current user available on each request, in the form of a &lt;code&gt;userId&lt;/code&gt; (which may be of type &lt;code&gt;string&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;On some route or other middleware, we now want to access the &lt;code&gt;userId&lt;/code&gt; like this:&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;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/some-route&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&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;res&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="o"&gt;=&amp;gt;&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="nx"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Hello, world! Your userId is &lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;userId&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;not available&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;TypeScript won't be happy with this, though. We will get an error like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Property 'userId' does not exist on type 'Request&amp;lt;ParamsDictionary, any, any, ParsedQs&amp;gt;'.ts(2339)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We need to tell the &lt;code&gt;Request&lt;/code&gt; interface that there is a &lt;code&gt;userId&lt;/code&gt; property. But how?&lt;/p&gt;

&lt;p&gt;The TypeScript 3 way of solving this (using &lt;code&gt;declare global&lt;/code&gt;) may still work, but it would give me a warning, due to an &lt;a href="https://github.com/typescript-eslint/typescript-eslint/blob/v4.6.0/packages/eslint-plugin/docs/rules/no-namespace.md"&gt;eslint rule&lt;/a&gt;, which basically states that &lt;code&gt;declare global&lt;/code&gt; is the old and outdated way.&lt;/p&gt;

&lt;p&gt;The new way is to use &lt;code&gt;declare module&lt;/code&gt;. In our example we can therefore introduce the &lt;code&gt;userId&lt;/code&gt; to Express' &lt;code&gt;Request&lt;/code&gt; type like this:&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;declare&lt;/span&gt; &lt;span class="kr"&gt;module&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;express-serve-static-core&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;Request&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;userId&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;... and voila, the warning is gone, and (more importantly) type safety through TypeScript is restored.&lt;/p&gt;

&lt;p&gt;(It isn't overly intuitive that the &lt;code&gt;Request&lt;/code&gt; type must be extended in the module &lt;code&gt;express-serve-static-core&lt;/code&gt;...)&lt;/p&gt;

&lt;p&gt;Now, what if you add a field to the session (assuming you are using &lt;a href="https://github.com/expressjs/session#readme"&gt;express-ession&lt;/a&gt;)? The additional field needs to be declared for the &lt;code&gt;Session&lt;/code&gt; type, inside the &lt;code&gt;express-session&lt;/code&gt; module, like this:&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;declare&lt;/span&gt; &lt;span class="kr"&gt;module&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;express-session&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;Session&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;someSessionVar&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>typescript</category>
      <category>express</category>
      <category>javascript</category>
      <category>node</category>
    </item>
  </channel>
</rss>
