Are unsound type systems wrong?
Unsoundness is important because soundness and expressiveness come at a trade-off.<p>Here's some code which is syntactically legal in both TypeScript and Flow, but the languages disagree on whether a type error is present:<p><pre><code>  type T = { // Legal decl in Flow, illegal in TS
    x: number;
    [s: string]: boolean;
  };
  const m: T = { x: 1, xz: true };
  m['xz'.substr(0, 1)] = true;
  m.x.toFixed(); // Crashes
</code></pre>
TypeScript is actually <i>more</i> sound than Flow in this example because it disallows the declaration of T in the first place. Flow allows this code and it fails due to a type error at runtime.<p>Yet in JavaScript this is an extremely common pattern - an object bag where some known property keys have a certain type, but "all the others" have a different type. You can't represent this in a bolt-on type system without forcing the developer to jump through enormous hoops proving that any lookup key <i>isn't</i> one of the "known" keys. By enforcing soundness at all costs, you lose the expressiveness needed to ergonomically describe this object.<p>Since most people don't directly aim guns at their feet, the unsoundness here is unimportant in practice. This is one place where I think Flow made the right trade-off to be unsound for the sake of practical usability for a common pattern.