Declare a delegate type in Typescript
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}`;
Solution 4
Type definition for a callable expression (this is a draft ok, for humans... not a BNF or anything formal):
callableType: (paramsDef) => returnType
paramsDef: MULTIPLE paramDef SEPARATED BY ,
paramDef: EITHER paramName: paramType
OR optionalParamName?: paramTypeWhenDefined
OR ...manyParamName: eachParamType[]
Example:
var func = something as ((...x: any[]) => any);
Then you can:
var result = func("a", "b", 2);
Dynalon
Updated on July 08, 2022Comments
-
Dynalon almost 2 years
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?
-
Alwyn almost 10 yearsNot quite the same, but the best we've got. I just hate having to declare interfaces all over the place when an anon strongly typed function should do.
-
Ryan Cavanaugh almost 10 yearsNot sure what you mean -- you can have anonymous function types as well.
-
Alwyn almost 10 yearsI want to declare a function that takes in a call back delegate eg. Func<string,int> in c#, how can this be declared in TypeScript? Using the lambda operator is used to declare an instance of a delegate not the type. The type is the anon delegate Func<string,int>. What's the equivalent syntax?
-
Ryan Cavanaugh almost 10 yearse.g.
function foo(x: (n: number) => string) { console.log(x(3)); }
, or equivalentlyfunction foo(x: { (n: number): string; }) { ... }
-
Robert Koritnik over 7 yearsFYI: These are called type aliases.
-
Steven Liekens about 6 yearsHow do you declare and export a function that is an instance of
Greeter
in a way that you get proper intellisense for the greeter function when it is imported in a different file? -
TheRubberDuck over 2 yearsNote that the
: string
on line 2 is not required; the type can be inferred based on being assigned to aGreeter
.