liveBook · Manning

Function

As explained in Essential TypeScript 5, Third Edition

A JavaScript function is a callable construct that encapsulates executable code and can accept inputs and produce a result.

A function groups executable code behind a call. JavaScript functions declare parameters and a body, but do not enforce argument types or require a fixed number of arguments. The values passed to a function can therefore change both its behavior and the type of its result. section 3.3.3 section 3.7

A sum with an unexpected result

In index.js, `function sumPrices(first, second, third) { return first + second + third; }` appears to add prices. Calling it with `100` and the string `"100"`, but no third argument, returns `"100100undefined"`: `+` concatenates after encountering the string, and the missing parameter is `undefined`. Calling it with three numbers returns `600`; calling it with only two numbers returns `NaN`. section 3.3.3

Choose parameter forms to match the calls a function must accept:

  • Give a parameter a default value when an omitted argument should have a defined replacement. This fixes the missing-number case, but does not prevent string concatenation. section 3.3.3
  • Use a rest parameter, such as `...numbers`, to capture an arbitrary number of arguments. Convert and check values before adding them if callers may supply strings or other values. section 3.3.3
  • Use an arrow function for a concise function expression, including callbacks. Do not assume it has the same `this` behavior as a regular function: an arrow function has no `this` value of its own. section 3.3.3 section 3.6.5
Listing 3.18 Converting and filtering parameters in the index.js file in the primer folder
let hatPrice = 100;
console.log(`Hat price: ${hatPrice}`);
let bootsPrice = "100";
console.log(`Boots price: ${bootsPrice}`);

function sumPrices(...numbers) {
    return numbers.reduce(function(total, val) {
        return total + (Number.isNaN(Number(val)) ? 0 : Number(val));
    }, 0);
}

let totalPrice = sumPrices(hatPrice, bootsPrice);
console.log(`Total: ${totalPrice} ${typeof totalPrice}`);

totalPrice = sumPrices(100, 200, 300);
console.log(`Total: ${totalPrice} ${typeof totalPrice}`);

totalPrice = sumPrices(100, 200, undefined, false, "hello");
console.log(`Total: ${totalPrice} ${typeof totalPrice}`);

The index.js listing develops `sumPrices` into a rest-parameter function that converts values with `Number` and substitutes zero when conversion produces `NaN`. Its calls return numeric totals even when arguments include a numeric string, `undefined`, or `"hello"`. section 3.3.3

TypeScript keeps standard JavaScript function syntax while making type assumptions explicit. Parameter and result annotations let the compiler check the types used in calls and returns. Optional parameters permit omitted arguments; defaults and rest parameters address other variations in argument count. Compiler options can reject unwanted null or undefined values and require a result from every code path. section 8.2 section 8.3

When a result type depends on which parameter types were supplied, TypeScript type overloads can describe those combinations; JavaScript itself does not provide function overloading. Assert functions can supply type information to the compiler, much like type guards. These features describe and check a function more precisely rather than changing how its JavaScript body is written. section 8.3 section 8.2

Functions also serve as application structure. A function assigned to an object property is a method, and a function object can itself hold properties such as static methods. Related functions can be exported by name from a module and imported individually where needed. section 4.2.6 section 4.5.5

Listing 4.32 The contents of the utils.js file in the primer folder
import { calculateTax } from "./tax.js";

export function printDetails(product) {
   let taxedPrice = calculateTax(product.price);
   console.log(`Name: ${product.name}, Taxed Price: ${taxedPrice}`);
}

export function applyDiscount(product, discount = 5) {
   product.price = product.price - discount;
}

The utils.js listing exports two named functions: `printDetails` calculates and displays a taxed price, while `applyDiscount` changes a product’s price and gives its discount parameter a default value. section 4.5.5

How Essential TypeScript 5, Third Edition covers it

How deep it goes
Works through coercion, missing arguments, defaults, rest parameters, and TypeScript annotations; also introduces overloads and assert functions.
Examples
Demonstrates a price-summing function with mixed arguments and a utils.js module exporting discount and display functions.
What it assumes
Assumes familiarity with JavaScript calls and values while developing the JavaScript type behavior needed to understand TypeScript.
What you can do after
Build it from scratch: define functions that handle argument counts and types deliberately, then annotate and check them with TypeScript.
How it connects
Connects functions to type coercion, rest parameters, arrow functions, type overloads, assert functions, object methods, and modules.

Also explained in

Compare how 20 books explain function →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Essential TypeScript 5, Third Edition. The section links point to the parts of the book it draws on.