TypeScript - Functions
TypeScript - Functions
Section titled “TypeScript - Functions”Functions are essential building blocks for creating readable, maintainable, and reusable code. They encapsulate a set of statements designed to perform a specific task. Organizing code into functions makes programs more logical and easier to manage.
In TypeScript, like JavaScript, functions are first-class citizens. They can be defined, passed around as arguments, returned from other functions, and assigned to variables.
TypeScript enhances JavaScript functions by adding explicit type annotations for parameters and return values, providing compile-time safety.
| Concept | Description |
|---|---|
| Defining a Function | Specifies the function’s name, parameters (with types), return type, and the block of code (body) to execute. |
| Calling a Function | Invoking the function by its name followed by parentheses (), passing any required arguments. |
| Return Values | Functions can return a value using the return keyword. The type of the returned value should match the function’s declared return type. Functions that don’t return a value have a void return type. |
| Parameters & Arguments | Parameters are variables listed in the function definition. Arguments are the actual values passed to the function when it’s called. |
Function Syntax
Section titled “Function Syntax”TypeScript supports several ways to define functions:
1. Named Function Declaration
Section titled “1. Named Function Declaration”function greet(name: string): string { return `Hello, ${name}!`;}
function logMessage(message: string): void { console.log(message);}
let greeting = greet("Alice"); // greeting is inferred as stringlogMessage(greeting);2. Function Expression (Anonymous Function)
Section titled “2. Function Expression (Anonymous Function)”Assigning a function to a variable. The function itself might be anonymous.
const add = function(x: number, y: number): number { return x + y;};
let sum: number = add(10, 5);3. Arrow Function Expression
Section titled “3. Arrow Function Expression”A concise syntax for function expressions, especially useful for inline functions and callbacks. Arrow functions capture the this value of the enclosing context (lexical this).
const multiply = (x: number, y: number): number => { return x * y;};
// Concise body (single expression, implicit return)const subtract = (x: number, y: number): number => x - y;
// Arrow function with no parametersconst logTime = (): void => { console.log(new Date()); };
// Arrow function with one parameter (parentheses optional)const square = (x: number): number => x * x;// const square = x => x * x; // Type inferred if possible, but explicit is often better
let product: number = multiply(4, 6);logTime();Function Parameters
Section titled “Function Parameters”Optional Parameters
Section titled “Optional Parameters”Parameters can be marked as optional by appending a ? to their name. Optional parameters must come after required parameters. If an optional parameter isn’t provided, its value is undefined.
function buildName(firstName: string, lastName?: string): string { if (lastName) { return `${firstName} ${lastName}`; } else { return firstName; }}
let name1 = buildName("Bob"); // Output: Boblet name2 = buildName("Bob", "Adams"); // Output: Bob Adams
console.log(name1);console.log(name2);Default Parameters
Section titled “Default Parameters”You can provide default values for parameters. If an argument isn’t provided for a default parameter (or if undefined is passed), the default value is used. Default parameters don’t strictly need to come after required parameters, but doing so often improves readability.
function calculateRate(price: number, rate: number = 0.05): number { return price * rate;}
let amount1 = calculateRate(1000); // Uses default rate 0.05 -> 50let amount2 = calculateRate(1000, 0.1); // Uses provided rate 0.1 -> 100
console.log(amount1);console.log(amount2);Note: A parameter cannot be both optional (?) and have a default value.
Rest Parameters
Section titled “Rest Parameters”Collect multiple arguments into a single array parameter using the rest syntax (...). The rest parameter must be the last parameter in the function definition and must be of an array type.
function sumAll(...numbers: number[]): number { let total = 0; for (const num of numbers) { total += num; } return total;}
let total1 = sumAll(1, 2, 3); // Output: 6let total2 = sumAll(10, 20, 30, 40); // Output: 100
console.log(total1);console.log(total2);Function Overloads
Section titled “Function Overloads”Function overloading allows defining multiple function signatures (parameter types and return type) for a single function name, followed by one implementation body. The implementation must have a signature compatible with all the overload signatures. TypeScript uses the overload signatures for type checking calls to the function.
// Overload signaturesfunction process(value: string): string;function process(value: number): number;function process(value: boolean): boolean;
// Implementation signature (must be compatible with overloads)function process(value: string | number | boolean): string | number | boolean { if (typeof value === 'string') { return value.toUpperCase(); } if (typeof value === 'number') { return value * 2; } return !value;}
let result1: string = process("data"); // Correctly inferred as stringlet result2: number = process(10); // Correctly inferred as numberlet result3: boolean = process(true); // Correctly inferred as boolean
console.log(result1); // Output: DATAconsole.log(result2); // Output: 20console.log(result3); // Output: false
// let errorResult = process({ a: 1 }); // Error: No overload matches this call.Overloads are useful for functions that behave differently based on the types or number of arguments passed.
Other Function Concepts
Section titled “Other Function Concepts”thisKeyword: Behavior depends on how the function is called. Arrow functions have lexicalthis, while standard functions often depend on the call site (e.g., object method, standalone call). TypeScript provides ways to explicitly typethis.- Recursion: Functions calling themselves. Requires a base case to prevent infinite loops.
- Higher-Order Functions: Functions that accept other functions as arguments or return functions.
- Generics: Creating reusable functions that can work with various types while maintaining type safety (covered in more advanced topics).
Best Practices
Section titled “Best Practices”- Always provide explicit type annotations for parameters and return values unless the type inference is obvious and trivial.
- Prefer arrow functions for callbacks and short, simple functions due to concise syntax and lexical
this. - Use
constfor function expressions unless you specifically need to reassign the variable. - Keep functions focused on a single task (Single Responsibility Principle).
- Use function overloads when a function truly handles different argument patterns based on type, but avoid overly complex overload sets.