Functions in TypeScript

The Authentication Bug That Shipped to Production

It was launch day for our new payment feature. At 2:47 PM, we went live. At 3:12 PM, user reports started flooding in: "Can't log in after adding a credit card."

I dove into the logs:

// auth.js - Our old JavaScript code
function authenticateUser(username, password, options) {
  // Sometimes we called it with 2 args
  // authenticateUser('alice', 'pass123')
  
  // Sometimes with 3 args
  // authenticateUser('alice', 'pass123', { rememberMe: true })
  
  // The new payment code called it like this:
  // authenticateUser('alice', 'pass123', true)
  // BUG! options was supposed to be an object, not a boolean
  
  if (options.rememberMe) {  // Crashed here when options was true
    setLongLivedToken();
  }
}

The problem? No function signature. The new developer saw a third parameter, assumed it was a boolean flag, and broke authentication for 1,200 active users.

Hotfix time: 45 minutes of downtime. Angry support tickets. Emergency rollback.

That night, I migrated our authentication module to TypeScript:

Result: The bug would have been caught at compile time. TypeScript prevented it from ever reaching production.

This article covers everything about function types that could have saved me 45 minutes of downtime and a very uncomfortable incident postmortem.


Function Type Basics

TypeScript adds type annotations to parameters and return values.

Basic Function Syntax

Return Type Inference


Optional Parameters

Parameters that may or may not be provided.

Basic Optional Parameters

Optional Parameters Must Be Last

Multiple Optional Parameters


Default Parameters

Parameters with default values.

Basic Default Parameters

Default Parameters with Types

Default vs Optional


Rest Parameters

Accept variable number of arguments as an array.

Basic Rest Parameters

Rest Parameters with Other Parameters

Rest Parameters with Union Types

Real-world pattern from my logging utility:


Function Type Expressions

Describing function types separately from implementation.

Basic Function Type

Function Types in Interfaces

Callback Function Types


Function Overloads

Multiple function signatures for the same function.

Basic Overloads

Overloads with Different Parameter Counts

Real-World Example: Search Function


This Parameter

Explicit typing for this context.

Basic This Parameter

This Parameter in Classes

Real pattern from my event handling:


Generic Functions

Functions that work with multiple types.

Basic Generic Function

Generic Array Functions

Generic Constraints

Multiple Type Parameters

Production example from my data transformation utilities:


Async Functions

Functions that return promises.

Basic Async Function

Error Handling in Async Functions

Async Function with Generic Return


Real-World Patterns

1. Request Handler Type

2. Middleware Pattern

3. Factory Pattern

4. Retry Pattern


Common Mistakes I Made

1. Not Typing Callback Parameters

Bad:

Good:

2. Forgetting Return Types

Bad:

Good:

3. Overusing Function Overloads

Bad:

Good:


Your Challenge

Build a type-safe HTTP client:


Key Takeaways

  1. Type all parameters and returns - explicit is better than implicit

  2. Optional parameters with ? - must come after required

  3. Default parameters - provide fallback values

  4. Rest parameters - variable-length arguments as array

  5. Function overloads - multiple signatures for same function

  6. Generic functions - work with multiple types safely

  7. Async functions - always return Promise<T>

  8. This parameter - explicit typing for context


What I Learned

The authentication incident taught me: function signatures are contracts.

In JavaScript, I wrote:

Parameters were documentation (if I remembered to write it). Types were runtime surprises. The new developer saw three parameters and guessed wrong.

In TypeScript:

The signature tells you:

  • What parameters are required

  • What types are expected

  • What's optional vs required

  • What you'll get back

No guessing. No assumptions. Just compiler-enforced truth.

The 45-minute outage cost us:

  • Lost revenue: ~$3,000

  • Support time: 8 hours

  • Trust: harder to measure

TypeScript's function types would have caught it in 0.5 seconds of compilation.

Type your functions. Your future self (and your users) will thank you.


Next: Advanced Types - Unions and Intersections

In the next article, we'll explore TypeScript's advanced type system. You'll learn how union types and type guards prevented a payment processing disaster that could have cost us $50,000.

Last updated