Daily reminder that TypeScript's type checker is not sound.

https://www.typescriptlang.org/play/?#code/C4TwDgpgBAcg9gOwK...

It is true, but it wasn't meant to be sound, so it's okay.

You can do this trick for type-checking emptiness of string literals

https://www.typescriptlang.org/play/?jsx=0#code/C4TwDgpgBAsg...

Daily reminder that the unsoundness in Typescript's type checker is a practical compromise applied to a language that was never designed to be type checked in this way, and furthermore that many developers feel that it strikes a good balance between formal correctness and practical usability.

This example is not only wrong for what you intend to demonstrate but even if it wasn't, it's not problematic. In typescript the proper way to do this is using branded types and exporting only the safe constructor, making anyone who wants to violate the invariant go out of their way, which is no different from the situation in any number of programming languages or scenarios.

  declare const brand: unique symbol;
  type NonEmptyString = string & { readonly [brand]: 'NonEmptyString' };

  // the ONLY non-cast way to produce one
  export function nonEmptyString(s: string): NonEmptyString | undefined {
    return s.length > 0 ? (s as NonEmptyString) : undefined;
  }

  export type { NonEmptyString };