Type a Declared Function in TypeScript
Here's how to define a type for a declared function.
Declare a function
It's straightforward to type a function signature -- that is, its parameters and return value. For example, string in, number out:
function parseItBoom(input: string): number {
return parseInt(input, 10);
}
Define a function type
But what if I want to type the function itself? Commonly, we rewrite as a variable binding:
type LeParser = (input: string) => number;
const parseItBoom: LeParser = (input) => {
return parseInt(input, 10);
}
But this removes our a lovely declaration, and I like function declarations.
How will we get the typechecking for LeParser
? We have to specify it at the point of usage. We cannot simply declare it and then attach a type and have TypeScript type-check it for us. Stylistically, it'd be nice to have the type check with a declaration only, but I don't think this is possible. But practically, no typing is needed until usage.
So, how do we type a function? Well, we can assign it, invoke it or refer to it.
Typecheck with assignment
This will typecheck:
const myParser: LeParser = parseItBoom;
Typecheck with invocation
This will typecheck:
const answer: number = parseItBoom("42")
Typecheck with reference
And this will typecheck:
function process(parse: LeParser) {
// etc, (assignment and invocation)
}
process(parseItBoom)
Avoid casting
You might be tempted to cast the function to the type. But this isn't safe:
function parseItBoom(input: string): number {
return parseInt(input, 10);
} as LeParser
We're forcing the compiler to accept the assertion of our type. If we changed this function implementation, the cast will prevent TypeScript from finding a new failure in usage.
Define function with a static member
Related to this topic of defining function types is the variation where the function has a static member. How do we define that?
If parseItBoom
had a radix
static number, we could define the type like this:
type LeParser = {
(input: string): number
radix: number
}
Where the implementation might look like this:
function parseItBoom(input: string): number {
return parseInt(input, parseItBoom.radix
}
parseItBoom.radix = 10