title: Typescript: User-Defined type guards for literal types?
body: <p>Note: I'm new to typescript. Prior to posting I read the <a href="https://www.typescriptlang.org/docs/handbook/advanced-types.html" rel="noreferrer">docs</a> regarding advance types and <a href="https://www.typescriptlang.org/docs/handbook/advanced-types.html#type-guards-and-differentiating-types" rel="noreferrer">type guards</a>. In addition I also read several related S.O. question (e.g. <a href="https://stackoverflow.com/questions/32713452/user-defined-type-guards-typescript">user defined type guards [typescript]</a>, and <a href="https://stackoverflow.com/questions/41984719/how-to-write-a-user-defined-type-guard-for-string-literal-types">How to write a user defined type guard for &quot;string&quot; | &quot;literal&quot; | &quot;types&quot;?</a>)</p>
  
  <p>Most similar to my question is the later question where you might have some custom type on a literal (in this instance <code>string</code>, but the solution should apply to <code>number</code> as well) e.g.</p>
  
  <pre><code>type Format = 'JSON' | 'CSV' | 'XML'
  </code></pre>
  
  <p>In the second question the user asks in regards to a solution of typescript's <code>keyof</code> key word and <strong>@Ryan Cavanaugh</strong>'s <a href="https://stackoverflow.com/a/41984915/5623899">answer</a> goes about this via changing the type from a <code>literal</code> to an <code>interface</code> and checking the keys of the interface:</p>
  
  <pre><code>// copy-pasted from answer for convenience
  interface McuParams {
      foo, bar, baz;
  }
  function isKeyOfMcuParams(x: string): x is keyof McuParams {
      switch (x) {
          case 'foo':
          case 'bar':
          case 'baz':
              return true;
          default:
              return false;
      }
  }
  </code></pre>
  
  <p>My question is specifically if there is a way to do user defined type guards using the type itself e.g.</p>
  
  <pre><code>const isFormat = (maybe:String|Format): maybe is Format =&gt; /* something goes here */
  </code></pre>
  
  <p>To my knowledge the following does not work (replacing just <code>/* something goes here */</code>):</p>
  
  <pre><code>// 1
  /* 
   * As stated in the docs "The right side of the instanceof needs to 
   * be a constructor function" but we have a literal
   */
  maybe instaceof Format
  
  //2
  /* As stated in the docs "typename" must be "number", 
   * "string", "boolean", or "symbol" 
   */
  typeof maybe === 'format'
  
  
  //3
  /* no idea */
  (&lt;Format&gt;maybe)
  
  </code></pre>
  
  <p>So is <strong>@Ryan Cavanaugh</strong>'s answer the only viable solution? It seems extremely verbose...</p>