Declare a delegate type in Typescript

Coming from a C# background, I want to create a datatype that defines a function signature. In C#, this is a delegate declared like this:

delegate void Greeter (string message);

public class Foo
{
    public void SayHi (Greeter g) {
        g("Hi!");
    }
}

Now, I want to achieve similar in Typescript. I know Typescript has no delegate types, but only lambdas. I came up with something like this:

class Foo {
    SayHi (greeter: (msg: String) => void) {
        greeter('Hi!');
    }
}

While this works, I want to reuse the method signature (msg:String) => void couple of times and think it would be cleaner to create a custom type - like the delegate in C#.

Any ideas how this can be done?


Solution 1:

In TypeScript, interfaces can have call signatures. In your example, you could declare it like this:

interface Greeter {
    (message: string): void;
}

function sayHi(greeter: Greeter) {
    greeter('Hello!');
}

sayHi((msg) => console.log(msg)); // msg is inferred as string

Solution 2:

You can create something like a delegate by using a type alias:

type MyDelegate = (input: string) => void;

which defines a type name for a function pointer, just as delegates do in C#. The following example uses it in combination with generic type parameters:

type Predicate<T> = (item: T) => boolean;

export class List<T> extends Array<T> {
    constructor(...items: T[]){
        super();
        for(let i of items || []){
            this.push(i);
        }
    }
    public hasAny(predicate?: Predicate<T>): boolean {
        predicate = predicate || (i => true)
        for(let item of this) {
            if(predicate(item)) return true;
        }
        return false;
    }
}

Solution 3:

Five years and many, many TS versions later I find myself using a simpler type definition for declaring function types:

type Greeter = (msg: string) => void;
const someGreeter: Greeter = (msg: string) => `Hi there with ${msg}`;