-
Notifications
You must be signed in to change notification settings - Fork 13k
Description
Currently (as of TypeScript 0.9), TypeScript supports overloading on constants, but string constants only.
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.
Motivation
My current motiviating example for this is in Lodash's _.flatten function: https://lodash.com/docs#flatten
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.
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.
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 (https://github.com/borisyankov/DefinitelyTyped/blob/master/lodash/lodash.d.ts#L848-L881). 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.
Design
Exactly the same as for string constants (https://github.com/Microsoft/TypeScript/blob/master/doc/spec.md#3.9.2.4), but with true/false values.
See below for examples:
interface MyClass {
serialize(x: true): string;
serialize(x: false): number;
serialize(x: boolean): string | number;
}
var obj: MyClass;
var aBoolean: boolean = Math.random() >= 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);