<p dir="auto">Currently (as of TypeScript 0.9), TypeScript supports overloading on constants, but string constants only.</p>
<p dir="auto">This seems like a slightly arbitrary restriction, although I do agree that strings are the most obvious case where this is necessary. I do think there is (at least) one more case that comes up frequently though: booleans.</p>
<h3 dir="auto">Motivation</h3>
<p dir="auto">My current motiviating example for this is in Lodash's _.flatten function: <a href="https://lodash.com/docs#flatten" rel="nofollow">https://lodash.com/docs#flatten</a></p>
<p dir="auto">This takes a boolean 2nd argument; a flag which changes the behaviour of the method slightly. If true, it recursively flattens, and if false it only flattens a single level.</p>
<p dir="auto">Lodash also has _.flatten / _.flattenDeep methods without boolean arguments that follow each of these behaviours respectively without the flag. While I think we can agree that generally using the different methods where possible is often better, this still gets a lot of use, and boolean flags for this sort of thing are pretty common generally.</p>
<p dir="auto">Notably, these two (recursive/non-recursive) behaviours do have different type signatures, as you can see in the DefinitelyTyped definitions of all three different methods (<a href="https://github.com/borisyankov/DefinitelyTyped/blob/master/lodash/lodash.d.ts#L848-L881">https://github.com/borisyankov/DefinitelyTyped/blob/master/lodash/lodash.d.ts#L848-L881</a>). The method with the boolean signature though has to be overly general to cover both cases, even though when the flag passed is constant we can easily be more specific at compile time.</p>
<h3 dir="auto">Design</h3>
<p dir="auto">Exactly the same as for string constants (<a href="https://github.com/Microsoft/TypeScript/blob/master/doc/spec.md#3.9.2.4">https://github.com/Microsoft/TypeScript/blob/master/doc/spec.md#3.9.2.4</a>), but with true/false values.</p>
<p dir="auto">See below for examples:</p>
<div class="highlight highlight-source-ts notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="interface MyClass {  
    serialize(x: true): string;   
    serialize(x: false): number;  
    serialize(x: boolean): string | number;  
}

var obj: MyClass;
var aBoolean: boolean = Math.random() &gt;= 0.5;

// Valid:
var x: string = obj.serialize(true);
var y: number = obj.serialize(false);
var z: string|number = obj.serialize(aBoolean);

// Not valid:
var a: number = obj.serialize(true);
var b: string = obj.serialize(false)

var c: number = obj.serialize(aBoolean);
var d: string = obj.serialize(aBoolean);"><pre class="notranslate"><span class="pl-k">interface</span> <span class="pl-smi">MyClass</span> <span class="pl-kos">{</span>  
    <span class="pl-c1">serialize</span><span class="pl-kos">(</span><span class="pl-s1">x</span>: <span class="pl-c1">true</span><span class="pl-kos">)</span>: <span class="pl-smi">string</span><span class="pl-kos">;</span>   
    <span class="pl-c1">serialize</span><span class="pl-kos">(</span><span class="pl-s1">x</span>: <span class="pl-c1">false</span><span class="pl-kos">)</span>: <span class="pl-smi">number</span><span class="pl-kos">;</span>  
    <span class="pl-c1">serialize</span><span class="pl-kos">(</span><span class="pl-s1">x</span>: <span class="pl-smi">boolean</span><span class="pl-kos">)</span>: <span class="pl-smi">string</span> <span class="pl-c1">|</span> <span class="pl-smi">number</span><span class="pl-kos">;</span>  
<span class="pl-kos">}</span>

<span class="pl-k">var</span> <span class="pl-s1">obj</span>: <span class="pl-smi">MyClass</span><span class="pl-kos">;</span>
<span class="pl-k">var</span> <span class="pl-s1">aBoolean</span>: <span class="pl-smi">boolean</span> <span class="pl-c1">=</span> <span class="pl-smi">Math</span><span class="pl-kos">.</span><span class="pl-en">random</span><span class="pl-kos">(</span><span class="pl-kos">)</span> <span class="pl-c1">&gt;=</span> <span class="pl-c1">0.5</span><span class="pl-kos">;</span>

<span class="pl-c">// Valid:</span>
<span class="pl-k">var</span> <span class="pl-s1">x</span>: <span class="pl-smi">string</span> <span class="pl-c1">=</span> <span class="pl-s1">obj</span><span class="pl-kos">.</span><span class="pl-en">serialize</span><span class="pl-kos">(</span><span class="pl-c1">true</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
<span class="pl-k">var</span> <span class="pl-s1">y</span>: <span class="pl-smi">number</span> <span class="pl-c1">=</span> <span class="pl-s1">obj</span><span class="pl-kos">.</span><span class="pl-en">serialize</span><span class="pl-kos">(</span><span class="pl-c1">false</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
<span class="pl-k">var</span> <span class="pl-s1">z</span>: <span class="pl-smi">string</span><span class="pl-c1">|</span><span class="pl-smi">number</span> <span class="pl-c1">=</span> <span class="pl-s1">obj</span><span class="pl-kos">.</span><span class="pl-en">serialize</span><span class="pl-kos">(</span><span class="pl-s1">aBoolean</span><span class="pl-kos">)</span><span class="pl-kos">;</span>

<span class="pl-c">// Not valid:</span>
<span class="pl-k">var</span> <span class="pl-s1">a</span>: <span class="pl-smi">number</span> <span class="pl-c1">=</span> <span class="pl-s1">obj</span><span class="pl-kos">.</span><span class="pl-en">serialize</span><span class="pl-kos">(</span><span class="pl-c1">true</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
<span class="pl-k">var</span> <span class="pl-s1">b</span>: <span class="pl-smi">string</span> <span class="pl-c1">=</span> <span class="pl-s1">obj</span><span class="pl-kos">.</span><span class="pl-en">serialize</span><span class="pl-kos">(</span><span class="pl-c1">false</span><span class="pl-kos">)</span>

<span class="pl-k">var</span> <span class="pl-s1">c</span>: <span class="pl-smi">number</span> <span class="pl-c1">=</span> <span class="pl-s1">obj</span><span class="pl-kos">.</span><span class="pl-en">serialize</span><span class="pl-kos">(</span><span class="pl-s1">aBoolean</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
<span class="pl-k">var</span> <span class="pl-s1">d</span>: <span class="pl-smi">string</span> <span class="pl-c1">=</span> <span class="pl-s1">obj</span><span class="pl-kos">.</span><span class="pl-en">serialize</span><span class="pl-kos">(</span><span class="pl-s1">aBoolean</span><span class="pl-kos">)</span><span class="pl-kos">;</span></pre></div>
<p dir="auto">For instance, in the following example where we declare the return type as an array type, we go from</p>
<div class="highlight highlight-source-ts notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="function foo(): blah[] {/**/"><pre class="notranslate"><span class="pl-k">function</span> <span class="pl-en">foo</span><span class="pl-kos">(</span><span class="pl-kos">)</span>: <span class="pl-smi">blah</span><span class="pl-kos">[</span><span class="pl-kos">]</span> <span class="pl-kos">{</span><span class="pl-c">/**/</span><span class="pl-kos"></span></pre></div>
<p dir="auto">to</p>
<div class="highlight highlight-source-ts notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="function foo(): blah[]{
/**/"><pre class="notranslate"><span class="pl-k">function</span> <span class="pl-en">foo</span><span class="pl-kos">(</span><span class="pl-kos">)</span>: <span class="pl-smi">blah</span><span class="pl-kos">[</span><span class="pl-kos">]</span><span class="pl-kos">{</span>
<span class="pl-c">/**/</span><span class="pl-kos"></span></pre></div>
<p dir="auto">Notice the lack of whitespace between the <code class="notranslate">blah[]</code> and the <code class="notranslate">{</code>.</p>