04 / 06

How to receive a function as a parameter?

In TypeScript (or JavaScript), you can receive a function as a parameter by specifying it as a type in the function signature. Here's how you can do it:

Specify the type of the function parameter, including its arguments and return type.
You can define the function type as an alias for better readability and reuse.
If the function you're passing might have optional arguments, you can define them in the type.
A common use case for functions as parameters is callbacks, especially in asynchronous programming.
Difficulty: 5/10
Topics: higher-order functions, function types, generic callbacks

Scenario Questions

0-2 years experience
  1. 1

    We need a utility that takes an array of numbers and a callback to transform each number. How would you type the callback parameter in TypeScript?

  2. 2

    If you have a function processItems(items: string[], handler: ???), what signature would you give handler so it can receive each string and return a boolean?

  3. 3

    What happens if you pass a function that expects two arguments to a parameter typed as (value: string) => void?

2-5 years experience
  1. 1

    You’re adding a pagination component that accepts a fetchPage callback to load data. The callback may return a Promise or a plain array. How would you define its type to handle both cases, and what trade‑offs does that introduce?

  2. 2

    During a bug hunt, you notice that a higher‑order function sometimes receives undefined for its callback, causing a runtime error. How would you guard against that in TypeScript, and what compile‑time checks could you add?

  3. 3

    Explain why a generic map<T, U>(arr: T[], fn: (item: T) => U): U[] might fail if fn is declared as (item: any) => any and how you’d fix it.

5-8 years experience
  1. 1

    Our team is building a plugin system where each plugin registers a register function that receives a context object and returns void. How would you design the type for the plugin registration function to ensure plugins can’t accidentally mutate the context, and what performance considerations arise at scale?

  2. 2

    We need to expose a public API that accepts user‑provided callbacks for logging and error handling. The callbacks may be synchronous or async, and we must preserve stack traces. How would you type these callbacks and enforce correct usage across multiple services?

  3. 3

    When refactoring a legacy codebase, you want to replace any callbacks with strongly typed ones without breaking existing callers. What migration strategy would you use, and how would you leverage conditional types to keep backward compatibility?

8+ years experience
  1. 1

    Our platform is moving from a monolith to micro‑services, and we want a shared TypeScript library that defines contract callbacks for event handling across services. How would you design the type definitions to support versioning, backward compatibility, and independent deployment?

  2. 2

    Consider a scenario where many teams use a common higher‑order function that accepts a callback with generic constraints. Over time, some teams need more specific parameters, causing type friction. How would you evolve the API to balance flexibility and type safety while minimizing breaking changes?

  3. 3

    We are evaluating whether to encode callback contracts as interfaces versus type aliases with overloads. What are the long‑term maintenance implications of each choice in a large, polyglot organization?

Follow-up Questions

  • Can you sketch a minimal implementation of the type you described?
  • What happens if the passed callback throws an error or returns the wrong type?
  • How does TypeScript infer the return type of a higher‑order function in this scenario?