Functions
## Learning Objectives
- Write typed function parameters
- Define return types
- Master arrow functions
- Use function types
- Work with optional and default parameters
## Basic Function Syntax
### Named Function
```typescript
function add(a: number, b: number): number {
return a + b;
}
let result: number = add(5, 3); // 8
```
### Function Expression
```typescript
const multiply = function(a: number, b: number): number {
return a * b;
};
```
## Parameter Types
### Typed Parameters
```typescript
function greet(name: string): string {
return `Hello, ${name}!`;
}
greet("Alice"); // "Hello, Alice!"
// greet(123); // Error: Argument of type 'number'
```
### Multiple Parameters
```typescript
function introduce(name: string, age: number): string {
return `${name} is ${age} years old`;
}
```
## Return Types
### Explicit Return Type
```typescript
function getRandomNumber(): number {
return Math.random();
}
// Void return
function logMessage(msg: string): void {
console.log(msg);
}
```
### Inferred Return Type
```typescript
function add(a: number, b: number) {
return a + b; // TypeScript infers: number
}
```
## Optional Parameters
Parameters with `?` are optional:
```typescript
function greet(name?: string): string {
if (name) {
return `Hello, ${name}!`;
}
return "Hello!";
}
greet("Bob"); // "Hello, Bob!"
greet(); // "Hello!"
```
### Optional vs Undefined
```typescript
// Both are optional
function example(a?: string, b?: number) { }
// With explicit undefined
function example2(a: string | undefined) { }
```
## Default Parameters
Default values when argument not provided:
```typescript
function greet(name: string = "Guest"): string {
return `Hello, ${name}!`;
}
greet("Alice"); // "Hello, Alice!"
greet(); // "Hello, Guest!"
```
### Default with Type
```typescript
function createUser(name: string, role: string = "user"): { name: string; role: string } {
return { name, role };
}
```
## Rest Parameters
Collect remaining arguments:
```typescript
function sum(...numbers: number[]): number {
return numbers.reduce((total, n) => total + n, 0);
}
sum(1, 2, 3); // 6
sum(1, 2, 3, 4, 5); // 15
```
### Rest with Regular Parameters
```typescript
function logMessage(level: string, ...args: string[]): void {
console.log(`[${level}]`, ...args);
}
logMessage("INFO", "Server", "started"); // [INFO] Server started
```
## Arrow Functions
### Syntax
```typescript
const add = (a: number, b: number): number => {
return a + b;
};
```
### Shorthand
```typescript
const add = (a: number, b: number): number => a + b;
const square = (x: number): number => x * x;
const greet = (name: string): string => `Hello, ${name}!`;
```
### No Parameters
```typescript
const getRandom = (): number => Math.random();
const logTimestamp = (): void => {
console.log(Date.now());
};
```
## Arrow Functions and `this`
### Problem with Regular Functions
```typescript
class Timer {
seconds: number = 0;
start() {
// 'this' is lost
setInterval(function() {
this.seconds++; // 'this' is not Timer
}, 1000);
}
}
```
### Solution with Arrow Functions
```typescript
class Timer {
seconds: number = 0;
start() {
// 'this' is preserved
setInterval(() => {
this.seconds++;
}, 1000);
}
}
```
## Function Types
### Type Annotation
```typescript
let myFunction: (a: number, b: number) => number;
myFunction = (x, y) => x + y;
myFunction = (x, y) => x * y;
// myFunction = "hello"; // Error
```
### In Function Parameters
```typescript
function operate(a: number, b: number, op: (x: number, y: number) => number): number {
return op(a, b);
}
let result = operate(10, 5, (x, y) => x + y); // 15
result = operate(10, 5, (x, y) => x - y); // 5
```
## Callback Types
```typescript
function fetchData(
callback: (data: string) => void,
errorCallback: (error: Error) => void
): void {
// Success
callback("Data received");
// Or error
// errorCallback(new Error("Failed"));
}
fetchData(
(data) => console.log(data),
(err) => console.error(err)
);
```
## Return Types and Generics
```typescript
function firstElement(arr: T[]): T | undefined {
return arr[0];
}
let num = firstElement([1, 2, 3]); // number | undefined
let str = firstElement(["a", "b"]); // string | undefined
```
## Overloaded Functions
Multiple function signatures:
```typescript
function reverse(str: string): string;
function reverse(arr: string[]): string[];
// Implementation
function reverse(strOrArr: string | string[]): string | string[] {
if (typeof strOrArr === "string") {
return strOrArr.split("").reverse().join("");
}
return strOrArr.reverse();
}
reverse("hello"); // "olleh"
reverse(["a", "b", "c"]); // ["c", "b", "a"]
```
## Constructor Functions
```typescript
class Person {
name: string;
age: number;
constructor(name: string, age: number) {
this.name = name;
this.age = age;
}
}
function createPerson(name: string, age: number): Person {
return new Person(name, age);
}
let person = createPerson("Alice", 30);
```
## Method Syntax
### In Classes
```typescript
class Calculator {
add(a: number, b: number): number {
return a + b;
}
static multiply(a: number, b: number): number {
return a * b;
}
}
let calc = new Calculator();
calc.add(2, 3); // 5
Calculator.multiply(2, 3); // 6
```
## Void Return in Callbacks
```typescript
function executeCallback(callback: () => void): void {
console.log("Before callback");
callback();
console.log("After callback");
}
executeCallback(() => {
console.log("Callback executed!");
});
```
## never Return
```typescript
function fail(message: string): never {
throw new Error(message);
}
function processValue(value: string | number): string {
if (typeof value === "string") {
return `String: ${value}`;
}
if (typeof value === "number") {
return `Number: ${value}`;
}
fail("Unexpected value type");
}
```
## Summary
- Functions can have explicit parameter and return types
- Use `?` for optional parameters
- Default parameters provide fallback values
- Rest parameters (`...args`) collect multiple arguments
- Arrow functions: `(x, y) => x + y`
- Arrow functions preserve `this` context
- Function types: `(a: number, b: number) => number`
- Use `void` when function doesn't return a value
- Use `never` for functions that never return
Comments
Comments powered by Giscus
To enable comments, add your Giscus embed code here.
Learn more about Giscus →