← Back to context

Comment by tylerhou

6 years ago

> It's obviously impossible for TS to guarantee that an array will not be empty at runtime, but I wish this specific case triggered some help from the type checker.

  type NonEmptyArray<T> = { head: T, rest: T[] };

  function makeNonEmptyArray<T>(array: T[]): NonEmptyArray<T> | null {
    if (array.length == 0) return null;
    return { head: array[0], rest: array.slice(1, array.length) };
  }

  function head<T>(array: T[]): T | null;
  function head<T>(array: NonEmptyArray<T>): T;
  function head(array: any): any {
    if (Array.isArray(array)) {
      if (array.length === 0) return null;
      return array[0];
    }

    if (typeof array === "object") {
      return array.head;
    }
  }

http://www.typescriptlang.org/play/#code/C4TwDgpgBAcg9gOwKIF...

It's impossible for Haskell to guarantee an array will not be empty at runtime as well; that's why we can write a new type + a smart constructor to track runtime properties.