Skip to content
Educora
Beginner15 min3 / 8

Typed functions

Add types to function parameters and return values, use optional, default and rest parameters, and describe function types.

Check yourself
In this lesson you will learn
  • Annotate parameters and return values
  • Use optional, default and rest parameters
  • Write function types like (a: number) => number and understand contextual typing
  • Know what the void and never types mean

A function is a kind of contract: what it accepts and what it returns. In JavaScript this contract lives only in the developer's memory or in comments, and comments quickly go out of date. In TypeScript the contract is written in the function's header, and the compiler checks that it is kept at every call — both when you write the function and when you use it.

Parameters and return values

Each parameter's type is written after its name with a colon. The type of the return value comes after the parentheses. The function below calculates a tip in a restaurant:

TypeScript
function calculateTip(bill: number, percent: number): number {
  return (bill * percent) / 100;
}

const tip = calculateTip(40, 15);
console.log(`Tip: ${tip} AZN`);
Expected output
Tip: 6 AZN

The compiler checks both sides of the contract. The caller has to pass all the arguments with the right types, and the function's body has to return the type it promised:

TypeScript
function calculateTip(bill: number, percent: number): number {
  return (bill * percent) / 100;
}

calculateTip(40);

function isAdult(age: number): boolean {
  if (age >= 18) {
    return 'yes';
  }
  return false;
}
Text
tip.ts:5:1 - error TS2554: Expected 2 arguments, but got 1.

5 calculateTip(40);
  ~~~~~~~~~~~~

  tip.ts:1:37
    1 function calculateTip(bill: number, percent: number): number {
                                          ~~~~~~~~~~~~~~~
    An argument for 'percent' was not provided.

tip.ts:9:5 - error TS2322: Type 'string' is not assignable to type 'boolean'.

9     return 'yes';
      ~~~~~~
The first mistake is the caller's, the second is inside the function itself. The compiler even tells you which argument is missing.

Optional, default and rest parameters

  • An optional parameter has a ? after its name: greeting?: string. Its type is really string | undefined, so it may be left out.
  • A parameter with a default value (currency = 'AZN') takes its type from that value — here string. If no argument is passed, the default is used.
  • A rest parameter (...numbers: number[]) collects any number of arguments into an array.
  • Optional parameters must come after the required ones.
TypeScript
function greet(name: string, greeting?: string): string {
  return `${greeting ?? 'Hello'}, ${name}!`;
}

function price(amount: number, currency = 'AZN'): string {
  return `${amount.toFixed(2)} ${currency}`;
}

function sum(...numbers: number[]): number {
  return numbers.reduce((total, n) => total + n, 0);
}

console.log(greet('Murad'));
console.log(greet('Murad', 'Salam'));
console.log(price(12.5), '|', price(12.5, 'USD'));
console.log(sum(1, 2, 3), sum());
Expected output
Hello, Murad!
Salam, Murad!
12.50 AZN | 12.50 USD
6 0
The ?? operator falls back to 'Hello' when greeting is not given.

Because an optional parameter may be undefined, TypeScript won't let you use it without a check. In greet we provided a fallback with ??; if we forget to, this happens:

TypeScript
function shout(name: string, greeting?: string): string {
  return `${greeting.toUpperCase()}, ${name}!`;
}
Text
shout.ts:2:13 - error TS18048: 'greeting' is possibly 'undefined'.

2   return `${greeting.toUpperCase()}, ${name}!`;
              ~~~~~~~~

Function types

In JavaScript, functions are ordinary values: you can store them in variables and pass them to other functions as arguments. So a function has a type too. A function type is written with arrow syntax: (a: number, b: number) => number — “a function that takes two numbers and returns a number”. It is handy to give such a type a name with type.

TypeScript
type Operation = (a: number, b: number) => number;

const add: Operation = (a, b) => a + b;
const multiply: Operation = (a, b) => a * b;

function calculate(x: number, y: number, op: Operation): number {
  return op(x, y);
}

console.log(calculate(6, 7, add));
console.log(calculate(6, 7, multiply));
console.log([1, 2, 3].map((n) => n * 10));
Expected output
13
42
[ 10, 20, 30 ]

Notice that in add we didn't write types for a and b, yet there is no error. This is contextual typing: because the function is stored in a variable of type Operation, TypeScript knows the parameters are number. The same goes for map: since the array holds numbers, n automatically becomes a number.

TypeMeaningExample
voidthe function returns nothing usefulfunction log(msg: string): void
neverthe function never finishes normally — for example, it always throwsfunction fail(msg: string): never
function typeparameters and return type(a: number, b: number) => number

Key points

  • Parameter types go after their names; the return type goes after the parentheses.
  • The compiler checks the number and types of arguments, and the returned value inside the body.
  • x?: T is optional and has the type T | undefined; x = value is a default; ...xs: T[] is a rest parameter.
  • A function type uses an arrow: (a: number, b: number) => number; contextual typing fills in the parameter types.
  • void means nothing is returned; never means the function never finishes normally.

Check yourself

10 questions. Every correct answer earns XP.

1 / 10
What does the type (a: number, b: number) => number describe?