TypeScript Function Overloads

In TypeScript, you can declare an overloaded function by declaring the function with a multiple invocation signatures.

interface Foo
{
    bar: {
        (s: string): number;
        (n: number): string;
    }
}

or

interface Foo {
    bar(s: string): number;
    bar(n: number): string;
}

The type checker of TypeScript works as expected:

var foo1: Foo = ...;

var n: number = foo1.bar('hello world'); // OK
var s: string = foo1.bar(123);           // OK
var a: boolean = foo1.bar(false);        // ERROR

However, you can’t actually define an overloaded function with multiple function definitions as in C# or Java. The compiler complains about “error TS2393: Duplicate function implementation”. This happens because the signatures of both bar functions are identical once their types are erased.

class FooClass implements Foo {
    bar(s: string): number {
        return s.length;
    }
	
    bar(n: number): string {
        return n.toString();
    }
}

is translated to

var FooClass = (function () {
    function FooClass() {
    }
    FooClass.prototype.bar = function (s) {
        return s.length;
    };
    FooClass.prototype.bar = function (n) {
        return n.toString();
    };
    return FooClass;
})();

To define an overloaded function in TypeScript, the function must be singular and perform appropriate dispatching internally using type guards.

class FooClass implements Foo
{
    public bar(s: string): number;
    public bar(n: number): string;
    public bar(arg: string | number): any 
    {
        if (typeof arg=== 'number')
            return arg.toString();
        if (typeof arg === 'string')
            return arg.length;
    }
}

When you declare a variable with FooClass, you can’t see bar(arg: string | number) method even though it is declared as public. It is automatically hidden by the more specifically typed overloads.

TypeScript’s function overloads are a bit more flexible than those of C# or Java in that an overloaded function can have different return types. Note that bar(arg: string) returns number while bar(arg: number) returns string.

One thought on “TypeScript Function Overloads

  1. Pingback: Thoughts on Intersection Types | Kwang Yul Seo

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s