Functions and generics

Type function parameters

Put type annotations on a function boundary so invalid calls fail before the function body executes.

Function parameters are boundaries. Inside the body you control the code; at the boundary, anyone can call with anything. Annotate what callers are allowed to pass:

function greet(name: string, times = 1) {
  return name.repeat(times)
}

Two things happen here. name: string is an explicit annotation. The default value = 1 lets TypeScript infer times as a number without one — and it also makes the parameter optional, since omitting it uses the default.

These calls are valid:

greet('Ada')
greet('Ada', 3)

A boolean name or string count fails before the function runs:

Argument of type 'boolean' is not assignable to parameter of type 'string'.

Compare that with plain JavaScript, where greet(true, 3) would reach .repeat() and throw at runtime, possibly in production. The annotation moves the failure to the call site, at compile time, with the caller’s file and line in the message.

Unlike variables, parameters usually need explicit annotations. There is no initializer to infer from, and under strict checking an unannotated parameter is an error: Parameter 'name' implicitly has an 'any' type.

Optional parameters

Mark a parameter with ? only when callers can genuinely omit it:

function greet(name: string, title?: string) {
  return title ? `${title} ${name}` : name
}

Inside the function, title is string | undefined. The implementation must handle both cases — that is the deal you make when you accept an optional argument. Here the truthiness check handles it, and greet('Lovelace', 'Countess') returns 'Countess Lovelace'.

Order matters too: optional parameters must come after required ones, because a call like greet(undefined, 'Ada') has no way to skip a leading parameter cleanly.

Do not make things optional to silence errors

Do not make required data optional just to silence call-site errors. That moves the same problem into every use inside the function: each read of the parameter now needs an undefined check. If a caller does not have the data, the fix is at that caller, not in the signature everyone else shares.

Exercise: add an optional punctuation parameter with a useful default. Inspect its inferred type inside the function.

Lesson completed

Take this course offline

Get every free book, course edition, and software download.

Get the download library →