TypeScript allows you to add type annotations to function parameters and return values, making your code more reliable and self-documenting.
Function Declarations
A traditional function declaration with type annotations:
function greet(name: string): string {
return `hola ${name}`;
}
The syntax is: function name(param: Type): ReturnType
Arrow Functions
Arrow functions provide a more concise syntax:
const greet2 = (name: string): string => `hola ${name}`;
const message = greet2('vegeta');
console.log(message); // "hola vegeta"
Arrow functions are especially useful for short, single-expression functions and for preserving the this context.
Returning Objects from Functions
Define interfaces for complex return types:
interface User {
uid: string;
username: string;
}
function getUser(): User {
return {
uid: '112d',
username: 'angelosgd',
};
}
Arrow Function Returning Objects
Wrap the object in parentheses to distinguish it from a function body:
const getUser2 = (): User => ({
uid: '12sd',
username: 'marianayt',
});
const user = getUser();
const user2 = getUser2();
The parentheses around the object ({...}) tell TypeScript you’re returning an object, not starting a function block.
Functions as Callbacks
Functions can be passed as arguments to array methods:
const myNumbers: number[] = [1, 2, 3, 4, 5];
myNumbers.forEach((value) => {
console.log(value);
});
Type Inference in Functions
TypeScript can often infer callback parameter types:
const myNumbers: number[] = [1, 2, 3, 4, 5];
// TypeScript knows 'value' is a number
myNumbers.forEach((value) => {
console.log(value);
});
Return Type Annotations
While TypeScript can infer return types, explicit annotations are recommended:
// ✓ Explicit return type (recommended)
function add(a: number, b: number): number {
return a + b;
}
// ✓ Also valid - type is inferred
function multiply(a: number, b: number) {
return a * b; // Inferred as number
}
Always annotate return types for public APIs and exported functions. This provides better documentation and catches errors early.
Best Practices
- Annotate parameters: Always add types to function parameters
- Annotate return types: Explicitly state what your function returns
- Use interfaces: Define interfaces for complex object parameters and returns
- Prefer arrow functions: For callbacks and short functions
- Use descriptive names: Function and parameter names should clearly indicate their purpose