title: String Union to string Array
body: <p>I have a string union type like so:</p>
  
  <pre><code>type Suit = 'hearts' | 'diamonds' | 'spades' | 'clubs';
  </code></pre>
  
  <p>I want a type-safe way to get all the possible values that can be used in this string union. But because interfaces are largely a design-time construct, the best I can do is this:</p>
  
  <pre><code>export const ALL_SUITS = getAllStringUnionValues&lt;Suit&gt;({
      hearts: 0,
      diamonds: 0,
      spades: 0,
      clubs: 0
  });
  
  export function getAllStringUnionValues&lt;TStringUnion extends string&gt;(valuesAsKeys: { [K in TStringUnion]: 0 }): TStringUnion[] {
      const result = Object.getOwnPropertyNames(valuesAsKeys);
      return result as any;
  }
  </code></pre>
  
  <p>This works okay, the function ensures I always pass an object where each key is an element in the string union and that every element is included, and returns a string array of all the elements. So if the string union ever changes, the call to this function will error at compile time if not also updated.</p>
  
  <p>However <strong><em>the problem is</em></strong> the type signature for the constant <code>ALL_SUITS</code> is <code>('hearts' | 'diamonds' | 'spades' | 'clubs')[]</code>. In other words, TypeScript thinks it is an array containing none or more of these values possibly with duplicates, rather than an array containing all the values just once, e.g. <code>['hearts', 'diamonds', 'spades', 'clubs']</code>.</p>
  
  <p>What I'd really like is a way for my generic <code>getAllStringUnionValues</code> function to specify that it returns <code>['hearts', 'diamonds', 'spades', 'clubs']</code>.</p>
  
  <p>How can I achieve this <strong><em>generically</em></strong> while being as <a href="https://en.wikipedia.org/wiki/Don%27t_repeat_yourself" rel="noreferrer">DRY</a> as possible?</p>