Typing the Actions
Functions are the engines of your application. They take data in (parameters), process it, and hand data back out (returns). If you don't strictly type what goes in and what comes out, your engine will inevitably break down. TypeScript secures the boundaries of your functions.
Typing Parameters
In standard JavaScript, a function will accept absolutely anything you pass to it, even if it causes a crash. In TypeScript, you explicitly define the type for every single parameter.
// The colon comes immediately after the parameter name
function calculateTax(amount: number, taxRate: number) {
return amount * taxRate;
}
// TypeScript now provides a forcefield around this function
// calculateTax("One Hundred", 0.20); // ERROR: Argument of type 'string' is not assignable to parameter of type 'number'.
// It also forces you to provide the exact right number of arguments
// calculateTax(100); // ERROR: Expected 2 arguments, but got 1.
Typing the Return Value
While TypeScript can often guess what a function returns based on its internal math, it is highly recommended to explicitly state the return type. This ensures that if your internal logic breaks, the compiler catches it before it returns corrupted data to the rest of the app.
// The return type annotation goes after the closing parenthesis of the parameters
function add(a: number, b: number): number {
return a + b;
}
// If we accidentally tried to return a string, TS would flag an error immediately.
function generateID(name: string): string {
// return Math.random(); // ERROR: Type 'number' is not assignable to type 'string'.
return `${name}-${Math.random()}`;
}
The 'void' Return Type
Many functions do not return a value. For example, a function that simply logs a message to the console, or a function that updates an external database but doesn't hand data back. For these, we use the void type.
// 'void' means this function completes an action but returns nothing useful
function logErrorToConsole(errorMessage: string): void {
console.error("APPLICATION ERROR: ", errorMessage);
// Notice there is no 'return' statement here.
}
Optional Parameters
Just like object properties, function parameters can be marked as optional using the question mark ?. Crucial Rule: Optional parameters must always come after all required parameters in the list.
// 'greeting' is required. 'name' is optional.
function sayHello(greeting: string, name?: string): string {
if (name) {
return `${greeting}, ${name}!`;
} else {
return `${greeting}!`;
}
}
console.log(sayHello("Welcome")); // Output: Welcome!
console.log(sayHello("Welcome", "Prince")); // Output: Welcome, Prince!
Arrow Functions
The typing syntax for Arrow Functions is slightly different visually, but logically identical. The return type still goes after the parameters, right before the arrow =>.
// Traditional Function Declaration
// function multiply(x: number, y: number): number { ... }
// Modern Arrow Function syntax
const multiply = (x: number, y: number): number => {
return x * y;
};
// Implicit return (one-liner)
const double = (num: number): number => num * 2;