flowtype: how can i overload function return types by argument count/types?

I don't have a complete solution for you, but I got partway there:

const items = [1, 2, 3];

type FirstType = ((_: void) => number) & ((n: number) => Array<number>);

const first: FirstType = (n?: number) => {
  if (n === undefined) {
    // returns a single Item
    return (items[0]: any);
  } else {
    // returns an array of Item
    return (items.slice(0, n): any);
  }
}

const a: number = first();
const b: Array<number> = first(2);

(tryflow)

The & is an intersection type, and it means that first must satisfy both of those types. You can see that the calls to first() typecheck the way you want.

Unfortunately, it does not seem like Flow is currently able to typecheck the body of first. Note that I had to cast the return values through any to escape the typechecker. If you are willing to forgo typechecking in the body of your function, you can at least get it where the functions are called.