Q:

Why must there be a general type declaration before the implementation when overloading string parameters?

TypeScript supports overloading string parameters so that methods that return any can be correctly typed when called with certain arguments.
This is defined in the spec in two places:
https://github.com/Microsoft/TypeScript/blob/master/doc/spec.md#1.8
https://github.com/Microsoft/TypeScript/blob/master/doc/spec.md#3.9.2.4
However, getting these to properly work can be difficult. Here is an example class that has a generic get. I want to provide specific types for when you pass the strings "a" or "b" to this function, and in all other cases have the return type be any.
I include the two specialized signatures, then provide a general signature, then provide the implementation, which has the general signature. The following code correctly reports error for the first two assignments to x and y, but if I remove the general signature (get(name: string): any), I get the error: Argument of type '"c"' is not assignable to parameter of type '"b"'. Why is the general signature require in addition to the signature on the implementation?
export default class Example {
  contents: any
  get(name: "a"): number
  get(name: "b"): string
  // Why is this required???
  get(name: string): any
  get(name: string): any { return this.contents[name] }
}

let w = new Example()

// Expected errors
// Type 'number' is not assignable to type 'string'.
let x: string = w.get("a")
// Type 'string' is not assignable to type 'number'.
let y: number = w.get("b")

// I get an error here only if I remove the general signature before the
// implementation of get.
// Argument of type '"c"' is not assignable to parameter of type '"b"'.
let z: string[] = w.get("c")

A:

Note the last line of section 6.2 of the spec, "Function overloads"

Note that the signature of the actual function implementation is not included in the type.

This makes sense, because the signature of the implementation needs to match all possible signatures, and if it were included in the final signature, this could lead to a more general signature than we actually want. For example:
function foo(type: "number", arg: number)
function foo(type: "string", arg: string)
function foo(type: "number" | "string", arg: number | string) {
    // impl here
}

The signature of the implementation is necessary due to the previous signatures, but if it were included in the final signature, the following would be allowed although it is exactly what we want to prevent:
foo("number", "string param")

