<?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: judehunter</title>
    <description>The latest articles on DEV Community by judehunter (@judehunter).</description>
    <link>https://dev.to/judehunter</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%2F465912%2F2bf6e335-10d5-41de-87cb-093ca4146f43.jpeg</url>
      <title>DEV Community: judehunter</title>
      <link>https://dev.to/judehunter</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/judehunter"/>
    <language>en</language>
    <item>
      <title>The only API stack (and workflow) you should be using.</title>
      <dc:creator>judehunter</dc:creator>
      <pubDate>Sun, 13 Sep 2020 01:09:11 +0000</pubDate>
      <link>https://dev.to/judehunter/the-only-api-stack-and-workflow-you-should-be-using-10o8</link>
      <guid>https://dev.to/judehunter/the-only-api-stack-and-workflow-you-should-be-using-10o8</guid>
      <description>&lt;p&gt;Over the years, I've tried multiple Node.js back-end technology stacks, and I can finally say I've found a suitable one that will help you rapidly develop your projects (and kickstart your startups!).&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;The REST framework&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Why?&lt;/strong&gt; I've extensively used both REST and GraphQL back-ends and I believe GraphQL is an overkill in most cases. While it's great for scalability, it is not the fastest way to develop an API for your project.&lt;/p&gt;

&lt;p&gt;My REST framework of choice is &lt;strong&gt;koa.js&lt;/strong&gt;.&lt;br&gt;
&lt;strong&gt;Why?&lt;/strong&gt; I believe it's one of the best frameworks when it comes to quick development of your API, since it makes it extremely easy to go from the idea to the implementation.&lt;/p&gt;

&lt;p&gt;The middleware stack is also very intuitive and relies on async/await.&lt;/p&gt;

&lt;p&gt;I also feel it's a lot better than Express and generally more lightweight.&lt;/p&gt;
&lt;h3&gt;
  
  
  &lt;strong&gt;TypeScript&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Why?&lt;/strong&gt; It is an extremely good and easy way to make your API type safe and develop more rapidly in the long run. It has saved  me a lot of headaches and I could not live without its IntelliSense suggestions.&lt;/p&gt;

&lt;p&gt;You'll also see that using TypeScript enables us to easily integrate &lt;code&gt;TypeORM&lt;/code&gt; into our project.&lt;/p&gt;
&lt;h3&gt;
  
  
  &lt;strong&gt;ESLint&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Why?&lt;/strong&gt; Consistency goes a long way. ESLint makes sure you and your co-workers don't yell at each other over code that - in their opinion - is not properly formatted. It can also track things like unused variables/imports and usages of &lt;code&gt;let&lt;/code&gt; instead of &lt;code&gt;const&lt;/code&gt;.&lt;/p&gt;
&lt;h3&gt;
  
  
  &lt;strong&gt;The Database&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;This depends on your use case. However, there are only two database types you should care about - relational and document-based databases.&lt;/p&gt;

&lt;p&gt;If you're not sure,&lt;br&gt;
I'd say for smaller projects you'd want to go with a document-based database, like MongoDB.&lt;br&gt;
However, when your project grows, you'll probably have certain relations between your entities. And thus, you should use a relational database, like MySQL or PostgreSQL (which is my database of choice).&lt;/p&gt;
&lt;h3&gt;
  
  
  &lt;strong&gt;TypeORM&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;For MongoDB, Mongoose may be more suitable.&lt;/em&gt;&lt;br&gt;
&lt;strong&gt;Why?&lt;/strong&gt; TypeORM is an Object-Relational Mapping library for typescript (and babel), which basically means you don't have to deal with raw SQL and you can use certain utilities, like automatic relation joining.&lt;/p&gt;

&lt;p&gt;The reason why TypeORM is so interesting is the fact that it uses decorators for entity synchronization. What that means is you won't have to use migrations in your development environment.&lt;/p&gt;

&lt;p&gt;Instead, you define a class and decorate 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="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Entity&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nx"&gt;User&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;PrimaryGeneratedColumn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;uuid&lt;/span&gt;&lt;span class="dl"&gt;'&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="c1"&gt;// automatic type detection thanks to reflection!&lt;/span&gt;
  &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Column&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="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="c1"&gt;// automatic date columns!&lt;/span&gt;
  &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;CreateDateColumn&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="nx"&gt;createdAt&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Date&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;TypeORM then uses that class to migrate the database and to make IntelliSense suggestions based on the fields.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why not?&lt;/strong&gt; Frankly, TypeORM is not beginner friendly, largely due to the docs being quite horrible. However, when you get a hang of it and use IntelliSense to your advantage, it becomes an incredibly powerful tool.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Git Flow&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Why?&lt;/strong&gt; This is a certain philosophy/workflow/strategy that works particularly well when working with git in teams (not particularly needed if you're not in a team). &lt;br&gt;
It defines what branches should be used for certain things, like features, releases, hotfixes.&lt;/p&gt;
&lt;h3&gt;
  
  
  &lt;strong&gt;.env&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Why?&lt;/strong&gt; Using &lt;code&gt;.env&lt;/code&gt; files for defining your environmental variables is pretty much a standard now. It lets you define different variables for your local machine and for the machine you're hosting your project on.&lt;/p&gt;

&lt;p&gt;Do not forget to add &lt;code&gt;.env&lt;/code&gt; to &lt;code&gt;.gitignore&lt;/code&gt;!.&lt;/p&gt;
&lt;h3&gt;
  
  
  &lt;strong&gt;File structure&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;I came up with a file structure that works well with this particular technology stack:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;src
├── entities
│   └── User.ts
├── modules
│   └── module-name
│       ├── module-name.router.ts
│       ├── module-name.service.ts
│       └── module-name.spec.ts
├── mw
├── utils
└── app.ts

e2e
└── test-name.e2e.ts
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Going from the top:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The &lt;code&gt;entities&lt;/code&gt; folder is where you should store your TypeORM entities&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;modules&lt;/code&gt; folder holds the different modules of your application (inspired by NestJS). For instance, an &lt;code&gt;auth&lt;/code&gt; module may have a router that has a &lt;code&gt;/auth/facebook&lt;/code&gt; route which in turn calls the &lt;code&gt;authorizeWithFacebook()&lt;/code&gt; function in the service file. It's important the router handles the HTTP stuff, and the service deals with pure data. This way, your unit tests (&lt;code&gt;.spec.ts&lt;/code&gt;) can call the service directly. Additionally, your routes should - most of the time - be prefixed with the module name.&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;mw&lt;/code&gt; folder is where you should store your custom middleware. You could also use the &lt;code&gt;utils&lt;/code&gt; folder for this.&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;utils&lt;/code&gt; folder is pretty much every other function that doesn't fit anywhere else.&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;e2e&lt;/code&gt; folder stores the end-to-end tests.&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;This workflow has proven most successful for my projects and is great for rapid development.&lt;/p&gt;

&lt;p&gt;Don't agree with me? Start a discussion in the comments!&lt;/p&gt;

&lt;p&gt;Happy coding! 🎉&lt;/p&gt;

</description>
      <category>node</category>
      <category>javascript</category>
      <category>webdev</category>
      <category>devops</category>
    </item>
    <item>
      <title>The caveats (and solutions) to generic type guards in TypeScript.</title>
      <dc:creator>judehunter</dc:creator>
      <pubDate>Tue, 08 Sep 2020 23:49:54 +0000</pubDate>
      <link>https://dev.to/judehunter/the-caveats-and-solutions-to-generic-type-guards-in-typescript-2o7a</link>
      <guid>https://dev.to/judehunter/the-caveats-and-solutions-to-generic-type-guards-in-typescript-2o7a</guid>
      <description>&lt;p&gt;When dealing with user data - especially in APIs - and inheritance, it's often difficult to generalize your code and follow the DRY principle.&lt;/p&gt;

&lt;p&gt;The TypeScript language uses a concept called &lt;strong&gt;type guards&lt;/strong&gt; 🛡️ - a clever compiler feature that will help you write safer code and deal with that angry and complaining compiler.&lt;/p&gt;

&lt;p&gt;The compiler uses guards to narrow down the type of your value and provide IntelliSense suggestions.&lt;/p&gt;

&lt;p&gt;Say we have a given inheritance model:&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;class&lt;/span&gt; &lt;span class="nx"&gt;Vehicle&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;brand&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nx"&gt;Aircraft&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nx"&gt;Vehicle&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;usage&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;civil&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;military&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="kd"&gt;class&lt;/span&gt; &lt;span class="nx"&gt;Car&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nx"&gt;Vehicle&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;drive&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;AWD&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;FWD&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;RWD&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;We are given a &lt;code&gt;secretVehicle&lt;/code&gt; object that we know extends &lt;code&gt;Vehicle&lt;/code&gt; in terms of properties it has. However, the object is not an instance of any of these classes.&lt;/p&gt;

&lt;p&gt;Thus, the &lt;code&gt;instanceof&lt;/code&gt; approach won't work, since it requires the left operand to be an instance:&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;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;secretVehicle&lt;/span&gt; &lt;span class="k"&gt;instanceof&lt;/span&gt; &lt;span class="nx"&gt;Car&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`This is a car with &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;secretVehicle&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;drive&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; drive`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="c1"&gt;// TypeScript doesn't complain, but this will never print!&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;What we can do instead, is check if our &lt;code&gt;secretVehicle&lt;/code&gt; has all the properties of our subclasses.&lt;/p&gt;

&lt;p&gt;We do that by either using reflection or by creating an actual instance of that class and looking up its keys with &lt;code&gt;Object.keys()&lt;/code&gt;:&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;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;hasAllKeys&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;T&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;obj&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Record&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;cls&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;new&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;T&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nx"&gt;obj&lt;/span&gt; &lt;span class="k"&gt;is&lt;/span&gt; &lt;span class="nx"&gt;T&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;properties&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;keys&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;cls&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
    &lt;span class="k"&gt;for&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;p&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;properties&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;p&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="nx"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;false&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="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can then use the guard to assure TypeScript that the &lt;code&gt;secretVehicle&lt;/code&gt; is actually of a given type.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;hasAllKeys&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;secretVehicle&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Car&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`This is a car with &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;secretVehicle&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;drive&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; drive`&lt;/span&gt;&lt;span class="p"&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;hasAllKeys&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;secretVehicle&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Aircraft&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`This is a &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;secretVehicle&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;usage&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; aircraft`&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;However, in some edge cases this solution is problematic. It may incorrectly check the properties when used with a class that has a custom constructor.&lt;/p&gt;

&lt;p&gt;Moreover, sometimes it's simply not what we need. The input data we get is often just a &lt;code&gt;Partial&amp;lt;T&amp;gt;&lt;/code&gt; instead of a &lt;code&gt;T&lt;/code&gt;, meaning some properties might be missing (e.g. the &lt;code&gt;id&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;To counter that, let's use a guard that checks for specific properties instead of all of them.&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;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;hasKeys&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;T&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;obj&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Record&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;properties&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kr"&gt;keyof&lt;/span&gt; &lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="p"&gt;)[]&lt;/span&gt;
  &lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nx"&gt;obj&lt;/span&gt; &lt;span class="k"&gt;is&lt;/span&gt; &lt;span class="nx"&gt;T&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;
    &lt;span class="nx"&gt;properties&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;p&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;p&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="nx"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="nx"&gt;properties&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="c1"&gt;// functional approach&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The TypeScript compiler is clever enough to figure out &lt;code&gt;T&lt;/code&gt; by itself, if we don't want to specify it.&lt;/p&gt;

&lt;p&gt;For instance, &lt;code&gt;hasKeys(secretVehicle, ['usage'])&lt;/code&gt; will infer &lt;code&gt;T&lt;/code&gt; to be of type &lt;code&gt;{usage: any}&lt;/code&gt; and thus, we will be able to use the &lt;code&gt;usage&lt;/code&gt; key inside of our if statement.&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;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;hasKeys&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;secretVehicle&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;usage&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;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`
    Not sure what this is,
    but it has a &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;secretVehicle&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;usage&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; usage!
  `&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;Alas, this forces us to operate on values of type &lt;code&gt;any&lt;/code&gt;.&lt;br&gt;
We can either pass the the type for that key:&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;hasKeys&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="na"&gt;usage&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;civil&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;military&lt;/span&gt;&lt;span class="dl"&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="nx"&gt;secretVehicle&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;usage&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;Or just simply pass the entire class:&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;hasKeys&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Aircraft&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;secretVehicle&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;usage&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;&lt;em&gt;This will also give us IntelliSense suggestions when defining the keys!&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Still, what if both our subclasses have the same fields, but of different types? The issue gets more complicated and may require the usage of reflection.&lt;br&gt;
However, we can overcome this problem by specifying a &lt;code&gt;type&lt;/code&gt; field in our base class to easily differentiate between 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;class&lt;/span&gt; &lt;span class="nx"&gt;Vehicle&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;brand&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;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Car&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Aircraft&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ofType&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;T&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;obj&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Record&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="kd"&gt;type&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;cls&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;new&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;T&lt;/span&gt;
  &lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nx"&gt;obj&lt;/span&gt; &lt;span class="k"&gt;is&lt;/span&gt; &lt;span class="nx"&gt;T&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;
    &lt;span class="nx"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;cls&lt;/span&gt;&lt;span class="p"&gt;()).&lt;/span&gt;&lt;span class="kd"&gt;constructor&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="c1"&gt;// or use another argument for the type field&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;ofType&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;secretVehicle&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Car&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`This is a car with &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;secretVehicle&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;drive&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; drive`&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 is a powerful language and using these constructs can help you use it to its full potential.&lt;/p&gt;

&lt;p&gt;Thank you for reading my first contribution to the &lt;code&gt;dev.to&lt;/code&gt; community.&lt;/p&gt;

&lt;p&gt;Happy coding! 🎉&lt;/p&gt;

</description>
      <category>typescript</category>
      <category>javascript</category>
      <category>productivity</category>
      <category>learning</category>
    </item>
  </channel>
</rss>
