TypeScript: Typing Function Inputs and Outputs
Think of function types as a contract defining what data goes in and what comes out. This is core to TypeScript, ensuring functions are called correctly. The footgun is relying on return type inference, which can hide bugs if logic changes unexpectedly.
WHY IT EXISTS: JavaScript is dynamically typed, meaning you can pass any type of data to a function. This flexibility often leads to runtime errors like undefined is not a function or NaN. TypeScript introduces static typing for functions to catch these errors during development, not in production. It enforces a contract for what a function expects and what it provides.
THE MENTAL MODEL: Think of a typed function as a specialized machine with clearly labeled input slots and one output chute. The labels (number, string, etc.) ensure you only put the right materials in. The output chute's label guarantees what kind of product will come out. This makes the function predictable and safe to use throughout your application.
HOW IT WORKS: You add types to function parameters using a colon after the parameter name, like (name: string). You specify the return type by adding a colon after the parameter list, like (): number. For a function add(x, y), the typed version becomes function add(x: number, y: number): number. TypeScript's compiler then checks every call to add to ensure it receives two numbers and that its return value is treated as a number. You can also define the function's "shape" separately, like let myAdd: (base: number, increment: number) => number;, which is useful for callbacks or assigning functions to variables.
WHEN TO USE IT: Always type your function parameters and return values in TypeScript. This is a primary benefit of using the language. It's especially critical for functions in shared libraries, API boundaries, and complex business logic where incorrect data types can cause cascading failures. Explicit types also serve as clear documentation for other developers.
WHEN NOT TO USE IT: There are very few cases where you'd intentionally omit function types in TypeScript. One might be in a quick, temporary script or a private helper function where types are obvious and constrained by the outer scope. However, even then, explicit typing is generally preferred for clarity. Relying on return type inference is common but can be a footgun if the function's logic changes in a way that alters the returned type unexpectedly.
ONE CANONICAL EXAMPLE: A simple JavaScript greeting function might be function greet(name) { return "Hello, " + name; }. This could be called with greet(123), resulting in the string "Hello, 123", which may not be intended. The typed TypeScript version enforces the contract: function greet(name: string): string { return "Hello, " + name; }. Now, calling greet(123) will cause a compile-time error, preventing the bug before the code ever runs.
Read the original → typescriptlang.org
Get five bites like this every day.
Tezvyn delivers a daily feed of 60-second tech bites with quizzes to lock in what you learn.