JS Guide
HomeQuestionsTopicsCompaniesResources
BookmarksSearch

Built for developers preparing for JavaScript, React & TypeScript interviews.

ResourcesQuestionsSupport
HomeQuestionsSearchProgress
HomeTopicstypescriptFunction Types
PrevNext
typescript
beginner
8 min read

Function Types

callbacks
functions
never
overloads
parameters
rest-parameters
return-types
void

TypeScript functions require parameter type annotations (return types are usually inferred), support optional parameters, default values, rest parameters, and function overloads — function type expressions describe callback signatures for higher-order functions.

Key Points

1Parameter Annotations Required

Function parameters must have explicit type annotations — TypeScript infers return types from the body but cannot infer parameter types.

2Optional and Default Parameters

Optional (param?: type) makes the parameter type | undefined. Default parameters (param = value) infer the type and are optional from the caller.

3Function Type Expressions

Describe callback signatures: (params) => ReturnType. Used in type aliases, interfaces, and higher-order function parameters.

4Function Overloads

Multiple call signatures for one function — provide precise return types based on input types. Implementation signature must be compatible with all overloads.

5void vs never

void means the return value should be ignored (callbacks). never means the function doesn't return at all (throws or infinite loops).

What You'll Learn

  • Type function parameters, return values, and optional/default/rest parameters
  • Write function type expressions for callbacks and higher-order functions
  • Use function overloads to provide precise return types based on input
  • Explain the difference between void and never return types

Deep Dive

Functions are the primary unit of behavior in JavaScript, and TypeScript provides several ways to describe their types.

Parameter and Return Types

Function parameters must be explicitly annotated — TypeScript doesn't infer parameter types (there's nothing to infer from):

TypeScript
function greet(name: string): string {
  return `Hello, ${name}`;
}

Return types are usually inferred from the function body — explicit annotations are optional but useful for public APIs where you want to guarantee a contract. If the function's implementation accidentally returns the wrong type, the explicit annotation catches it.

Arrow Functions

Arrow functions follow the same rules: const add = (a: number, b: number): number => a + b;. Type inference works the same way — return type is inferred, parameters need annotations.

Optional and Default Parameters

Optional parameters use ?: function log(message: string, level?: string). The parameter's type becomes string | undefined. You can't put optional parameters before required ones.

Default parameters provide a fallback value: function log(message: string, level = 'info'). TypeScript infers the type from the default value, so you don't need both ? and a type annotation. Default parameters are optional from the caller's perspective.

Rest Parameters

Rest parameters collect remaining arguments into a typed array: function sum(...numbers: number[]): number. You can use tuple types for rest parameters when the arguments have different types: function make<T>(...args: [name: string, value: T]). Labeled tuple elements (name:, value:) improve IDE hints.

Function Type Expressions

To describe a function's type (for callbacks, higher-order functions), use type expressions:

TSX
type Callback = (error: Error | null, result: string) => void;
type Comparator<T> = (a: T, b: T) => number;

Function type expressions use => (not :) for the return type. They can be used in type aliases, interfaces, parameter types, and generic constraints.

Function Overloads

Overloads describe multiple call signatures for a single function:

TypeScript
function createElement(tag: 'input'): HTMLInputElement;
function createElement(tag: 'div'): HTMLDivElement;
function createElement(tag: string): HTMLElement;
function createElement(tag: string): HTMLElement {
  return document.createElement(tag);
}

Overload signatures (the first three lines) define what callers see. The implementation signature (last) must be compatible with all overloads but is not callable directly. Overloads provide more precise return types based on input values.

In modern TypeScript, generic conditional types often replace overloads with less boilerplate.

void vs undefined Return

void means the return value should be ignored — callbacks typed as () => void are allowed to return any value (the caller just won't use it). undefined means the function must explicitly return undefined or return nothing. Use void for callbacks, undefined when you need an explicit return type.

never Return Type

Functions that never return (throw errors, infinite loops) have return type never: function fail(message: string): never { throw new Error(message); }. This is different from void — void returns (with undefined), never doesn't return at all.

Key Interview Distinction

Parameters need explicit type annotations; return types are usually inferred. Optional parameters use ?, default parameters infer their type. Function type expressions describe callback signatures with =>. Overloads provide multiple call signatures with more precise return types. void means "ignore the return"; never means the function never returns.

Fun Fact

The void return type in TypeScript has a surprising behavior: a function typed as () => void can actually return any value — TypeScript just ensures the caller doesn't use it. This exists because JavaScript callbacks frequently return values that are ignored (like Array.forEach's callback), and making void strict would break nearly all callback patterns.

Learn These First

Basic Types

beginner

Continue Learning

Generics

intermediate

Interfaces vs Type Aliases

beginner

Practice What You Learned

How do you type functions in TypeScript?
junior
functions
Functions can be typed by annotating parameters and return type. TypeScript infers return types when possible. Use function type expressions for callbacks, optional/default parameters for flexibility, and overloads for multiple signatures.
Previous
Enums vs Union Types
Next
Generics
PrevNext