title: What's the difference between TypeScript const assertions and declarations?
body: <p>I just read about the new <code>const</code> assertion feature in TypeScript 3.4 RC and I'm not seeing how it does anything differently from using <code>const</code> declarations.</p>
  
  <p>I tested this out using an example from the <a href="https://devblogs.microsoft.com/typescript/announcing-typescript-3-4-rc" rel="nofollow noreferrer">announcement page</a> that apparently demonstrates how using <code>as const</code> (<code>const</code> assertion) prevents literal types from being widened (e.g., <code>"circle"</code> to <code>string</code>).</p>
  
  <pre><code>// Example from official announcement
  function getShapes() {
    let result = [
      { kind: "circle", radius: 100 },
      { kind: "square", sideLength: 50 },
    ] as const;
  
    return result;
  }
  
  for (const shape of getShapes()) {
    if (shape.kind === "circle") {
      console.log("Circle radius", shape.radius);
    } else {
      console.log("Square side length", shape.sideLength);
    }
  }
  
  // Output:
  // Circle radius 100
  // Square side length 50
  </code></pre>
  
  <p>However, when I removed the <code>const</code> assertion and used a <code>const</code> declaration instead, nothing changed in the compiler output <em>or</em> console output and no errors were thrown.</p>
  
  <pre><code>// Altered getShapes function
  function getShapes() {
    const result = [
      { kind: "circle", radius: 100 },
      { kind: "square", sideLength: 50 },
    ];
  
    return result;
  }
  </code></pre>
  
  <p><strong>So what's the difference?</strong> The announcement page lists three reasons to use <code>const</code> assertions:</p>
  
  <blockquote>
    <p>&bullet; no literal types in that expression should be widened (e.g. no going from "hello" to string)<br>
    &bullet; object literals get readonly properties<br>
    &bullet; array literals become readonly tuples</p>
  </blockquote>
  
  <p>but it doesn't explain how assertions and declarations are different.</p>