Skip to main content

Functions & Operators

Defining Functions

Functions in TypeScript are typed similarly to variables.

function add(a: number, b: number): number {
return a + b;
}

Avoid explicitly defining return types — let TypeScript infer them. Inferred return types are more flexible and accurate.

Void Type

If a function doesn't return anything, its return type is void.

function logMessage(msg: string): void {
console.log(msg);
}

void and undefined are different: void means the function doesn't return a usable value, while undefined means it explicitly returns undefined.

Optional Parameters

Use ? to mark a parameter as optional.

function greet(name: string, greeting?: string) {
console.log(`${greeting ?? "Hello"}, ${name}!`);
}

greet("Ajay"); // Hello, Ajay!
greet("Ajay", "Hey"); // Hey, Ajay!

Destructured and Rest Parameters

Rest Parameters

Capture an indefinite number of arguments as an array. Rest parameters (...rest) must always come at the end of the parameter list.

function resParameters(a: string, b: number, ...c: string[]) {
console.log(a, b, c);
}

resParameters('asd', 3, 'string', 'string', 'ajay');
// Output: asd 3 [ 'string', 'string', 'ajay' ]
// Practical use — sum any number of numbers
function sum(...nums: number[]) {
return nums.reduce((pre, curr) => pre + curr, 0);
}

console.log(sum(1, 2, 44)); // 47

Destructured Parameters

You can destructure objects directly in function parameters and type them inline.

function greet({ first, second }: { first: string; second: number; third: 'string' }) {
console.log(first, second);
}

greet({ first: 'Ajay', second: 34, third: 'string' });

Destructured + Rest Parameters Together

function desRest({ a, b, ...rest }: {
a: number;
b: string;
c: string[];
d: number[];
}) {
console.log(a, b, rest);
}

desRest({ a: 2, b: 'ajay', c: ['ad', 'ad'], d: [2, 343] });
// Output: 2 'ajay' { c: ['ad', 'ad'], d: [2, 343] }

Typing Variables as Functions

You can define a function signature type and reuse it.

type MathOperation = (a: number, b: number) => number;

function runOperation(a: number, b: number, operation: MathOperation) {
return operation(a, b);
}

const add: MathOperation = (a, b) => a + b;
const subtract: MathOperation = (a, b) => a - b;

runOperation(10, 5, add); // → 15
runOperation(10, 5, subtract); // → 5

This pattern is useful for passing callbacks, strategy patterns, and higher-order functions.