3
votes

Apologies if this is a bit of a dumb question. I've heard a little about call signatures in Typescript, but I don't understand exactly what they do. The Typescript documentation says:

In JavaScript, functions can have properties in addition to being callable. However, the function type expression syntax doesn’t allow for declaring properties. If we want to describe something callable with properties, we can write a call signature in an object type:

type DescribableFunction = {
  description: string;
  (someArg: number): boolean;
};
function doSomething(fn: DescribableFunction) {
  console.log(fn.description + " returned " + fn(6));
}

The documentation doesn't give any examples on how you would actually call doSomething (nor have pretty much any of the resources I've found on the topic), and I'm confused as to what it means by "something callable with properties". And what exactly does (someArg: number): boolean; mean? It looks like it's defining a function with a return type of boolean that takes a number argument named someArg, but passing in a function doesn't do anything. So... what exactly does it mean? Again, I've researched call signatures, but everything I've found pretty much just says "call signatures describe functions in detail", which isn't very helpful. What exactly are call signatures?

2
A call signature simply defines the arguments that function accepts (and their types) and the type returned by the function. If an interface has a call signature it means that the value it's describing must be a function. If a function implement a call signature that means it's arguments and return type must conform to that call signature.Alex Wayne

2 Answers

4
votes

how you would actually call doSomething

It's a function, so you'd call it (either from inside doSomething or from outside it) like you would any function: the fn(6) is an example of calling it.

and I'm confused as to what it means by "something callable with properties"

Functions are a special kind of object in JavaScript, and any object can have arbitrary key-value pairs associated with them. It's usually weird to see, but it's possible:

const myFn = (someArg) => {
  return someArg > 5;
};
myFn.description = 'checks if arg is greater than 5';

console.log(myFn(10));
console.log(myFn.description);

That's in plain JavaScript. TypeScript works the same way, except that you need to type things properly.

And what exactly does (someArg: number): boolean; mean? It looks like it's defining a function with a return type of boolean that takes a number argument named someArg,

Exactly right.

but passing in a function doesn't do anything

It should. Here's an example in JS:

const myFn = (someArg) => {
  return someArg > 5;
};
myFn.description = 'checks if arg is greater than 5';


function doSomething(fn) {
  console.log(fn.description + " returned " + fn(6));
}


doSomething(myFn);
0
votes

The (someArg: number): boolean in DescribableFunction means that any function that is to mimic DescribableFunction must:

  1. Have one argument with type number
  2. Return type must be a boolean

If it meets those conditions, it is now eligible to use the (object)DescribableFunction properties.

For it to be able to take the role of the object, it must define all properties of the object with the corresponding type. From your example

type DescribableFunction = {
  description: string;
  (someArg: number): boolean;
};
function doSomething(fn: DescribableFunction) {
  console.log(fn.description + " returned " + fn(6));
}

Let us say the function "callable" wants to act as the object, then

const callable = (num) => {
    return num > 5;
}

From the code above, you can see that the callable function meets the first two conditions required(i.e., it has an argument with type number and a return type of boolean). Next, it should define the properties of DescribableFunction alongside their correct type.

callable.description = "Number is greater than 5";

Now, it has fulfilled all the conditions. Next, let's call the function doSomething

doSomething(callable)

The output will be

Number is greater than 5 returned true