Looking up the Input and Output Types of a Function using the Parameters & ReturnType Utility Types
Learn how you can look up the parameter and return types of a function that don't have explicit types, or their types aren't exported.
Today’s topic is rather small and was inspired by this Substack Note, which I posted earlier this week.
In an earlier issue, I looked at the typeof and keyof operators and how we can use them to look up types for variables. While this covered most use cases, this didn’t cover all use cases and there is one - Functions.
Let’s say you want to get a functions call signature of a function inside a library beyond your control, and the library has no exported types. Fortunately for us, Typescript provides two very useful utility types - Parameters
and ReturnType
, and they help us reference the functions parameter type and the return type, respectively.
TypeScript provides several utility types to facilitate common type transformations. These utilities are available globally. - Typescript Docs
Let’s see them in action:
We will see start with a very simple function, that calculates the square of a rectangle:
function CalculateSquare(height: number, length: number) {
return height * length;
}
Using Parameters
utility Type
To get the parameters of a function, we are going to use the Parameters
utility type to get the type of the above functions.
type SquareParams = Parameters<typeof CalculateSquare>
We are using the typeof
operator, to reference the function’s type and then combine it with the Parameters
utility type to get our parameters, which we get back as tupple.
A tuple type is an array with a predefined length and predefined types in each index position in the array.
And this is the type we get back:
In our case the following tupple:
type SquareParams = [height: number, length: number]
We get a tuple back because functions accept positional arguments, i.e. each parameter needs to be in a specific position and in the correct order when calling the function. Javascript doesn't support named parameters.
Like with every type, you can use tuples array index position to reference to a type at the specific index position, as shown below.
type FirstArg = SquareParams[0];
type SeconArg = SquareParams[1];
And this is what you get back:
If you tried to access an index position, just as shown below:
type ThirdArg = SquareParams[2]
You would get the following error:
Tuple type '[height: number, length: number]' of length '2' has no element at index '2'.
Using ReturnType
utility type
To get a functions return type, we will use the RetuurnType in combination with the typeof
, as shown below.
type SquareReturnType = ReturnType<typeof CalculateSquare>
And our case, we are going to get the return type of number:
This is not a tuple, like the Parameters utility type we discussed previously but represents the actual return type of the functions, whatever it is, as shown below.
function Calculate(height: number, length: number) {
return {
square: height * length,
parameter: (height + length) * 2
};
}
type SquareReturnType = ReturnType<typeof Calculate>
And this is what we get back:
Why use the typeof
Operator?
If you may have noticed, we are using the typeof
in combination with the utility types above. This is because, function declaration exists in the variable space in Typescript and Javascript, and the typeof
operator allows us to reference the type of the function.
Remember, in Javascript and by extension Typescript, functions are first-class citizens and can be passed around just like any other variable and we need a way to add type annotations to them.
In such a case, such as when we are dealing with the function type and not variable, we can drop the typeof
operator.
type Calculate = (height: number, width: number) => {
parameter: number;
area: number;
};
type SquareReturnType = ReturnType<Calculate>
And these are the results:
Conclusion
In this issue, we discussed two Typescript Utility types - Parameters
and ReturnType
to help us reference the types of a function. Using the two utility types in combination with the typeof
operator, we get back the types, that we can use within our codebase, that’s accurate.
And that’s it for today, thank you for reading, and until next time, keep on learning.
❤️ Please share and/or like if you enjoyed the issue and show your support.