TypeScript Survival Guide

Favorite typescript videos

008 — The Function Type in TypeScript (params, defaults, void)

Full companion narrative for TypeScript Tutorial — The Function Type: inferred vs explicit function types, typed/optional/default parameters, return types, and void vs undefined

Video: 008 · TypeScript Tutorial - The Function Type in TypeScript · watch · 8:14 · Net Ninja TypeScript tutorial series

Source: this is a written companion to the video. Part of the Favorite TypeScript Videos curated path, module 04 (functions and generics). The first function lesson: how function types are inferred, how to declare them, and how parameters and return types are typed.

inferred function type

A variable initialized with a function is inferred to hold a function, the same way a variable initialized with a string or boolean is inferred as string/boolean. Reassigning it to a non-function afterwards is a type error.

let greet = () => {
	console.log("hello, world");
};

// Error: Type 'string' is not assignable to type '() => void'
greet = "hello";

explicit Function type (capital F)

Instead of initializing immediately, a variable can be declared ahead of time as holding some function, then assigned later. Unlike string/boolean/number, the Function type name is capitalized.

let greet: Function;

// Error: Type 'string' is not assignable to type 'Function'
// greet = 'hello';

greet = () => {
	console.log("hello, again");
};

editor showing let greet: Function with the arrow-function assignment

typed parameters

Parameter types are annotated with a colon after each parameter name. Arguments passed at the call site must match, or compilation fails.

const add = (a: number, b: number) => {
	console.log(a + b);
};

add(5, 10); // logs 15
add(5, "10"); // Error: Argument of type 'string' is not assignable to parameter of type 'number'

Omitting a required argument is also an error — every required parameter must be supplied.

optional parameters (?) and union types

Appending ? to a parameter makes it optional. A union type (e.g. number | string) widens what the parameter accepts. An omitted optional parameter is undefined at runtime.

const add = (a: number, b: number, c?: number | string) => {
	console.log(a + b);
	console.log(c);
};

add(5, 10); // logs 15, then undefined

default parameters

A default value makes a parameter effectively optional without needing ? — do not use both together. When the caller omits the argument, the default applies; when the caller supplies one, it overrides the default.

const add = (a: number, b: number, c: number | string = 10) => {
	console.log(a + b);
	console.log(c);
};

add(5, 10); // logs 15, then 10 (default)
add(5, 10, 20); // logs 15, then 20 (override)
add(5, 10, "20"); // logs 15, then '20' — allowed by the union type

editor showing the add function with default parameter and call sites

(On screen the default literal reads 18 and the final call reads add(5, 10, '20');; the spoken walkthrough uses 10. Either literal demonstrates the same mechanism.)

Rule of thumb: required parameters first, optional/defaulted parameters last, or positional arguments get mixed up.

inferred return types

When a function returns a value, TypeScript infers the return type, and any variable initialized from the call inherits that type.

const minus = (a: number, b: number) => {
	return a + b;
};

let result = minus(10, 7); // result: number

// Error: Type 'string' is not assignable to type 'number'
result = "hello";

explicit return-type annotation

The return type can be declared explicitly after the parameter list with a colon. It is redundant when inference already covers it, but useful as self-documentation on larger functions so readers see the contract at a glance.

const add = (a: number, b: number, c: number | string = 10): number => {
	console.log(a + b);
	console.log(c);
	return a + b;
};

void vs undefined

A function that logs but returns nothing still has a return type: void — a complete absence of any return value (visible in the editor hover tooltip as => void). Do not confuse it with undefined:

  • undefined = a real value, e.g. what an omitted optional parameter holds.
  • void = no value at all. When compiled to JavaScript it surfaces as undefined at runtime, but in TypeScript the two are distinct types.

full evolved example (end of lesson)

let greet: Function;

// greet = 'hello'; // Error

greet = () => {
	console.log("hello, again");
};

const add = (a: number, b: number, c: number | string = 10) => {
	console.log(a + b);
	console.log(c);
};

add(5, 10, "20");

Next video teaser: pinning down exactly which functions a variable may hold — 010 — Function Signatures.

Prev: 007 — Project Structure with tsconfig · Next: 009 — Type Aliases

Module 04 covered: inferred function type, explicit Function type, typed parameters with arity enforcement, optional (?) and default parameters with required-first ordering, inferred versus explicit return types, void versus undefined; signatures and generics come later. Transcript notes: booleans, Function capitalized versus lowercase primitives, greet, TypeScript, const minus/let result; frames 1-5 and 7-9 are talking-head shots, code in frames 6 and 10.