Parameters Utility Type in TypeScript

Parameters<T> extracts the parameter types of a function as a tuple. Use it to reuse parameter types without duplicating them.

5 min read

The TypeScript Parameters utility type extracts the parameter types from a function type as a tuple. If a function takes a string, a number, and a boolean, Parameters gives you [string, number, boolean]. It is the inverse of ReturnType: where ReturnType captures what a function produces, Parameters captures what it consumes.

The most practical use is building wrapper functions. You want a wrapper to accept exactly the same arguments as the original function, without duplicating the parameter types by hand.

typescripttypescript
function saveToDatabase(entity: string, data: Record&lt;string, unknown&gt;) {
  console.log(`Saving ${entity}:`, data);
}
 
type SaveParams = Parameters&lt;typeof saveToDatabase&gt;;

SaveParams resolves to [entity: string, data: Record&lt;string, unknown&gt;]. It is a tuple with named elements, so autocomplete shows the parameter names when you use the type elsewhere.

How Parameters works

Parameters takes a function type and produces a tuple of its parameter types. The tuple preserves both the types and the labels of the original parameters.

typescripttypescript
function connect(host: string, port: number, useTls: boolean): void {
  // implementation
}
 
type ConnectArgs = Parameters&lt;typeof connect&gt;;

ConnectArgs resolves to [host: string, port: number, useTls: boolean]. The labels host, port, and useTls are preserved, which improves autocomplete when the tuple is used later.

For a function with no parameters, Parameters returns an empty tuple. For a function with rest parameters, the rest element appears as an array type at the end of the tuple.

Building wrapper functions with Parameters

The strongest use case is writing wrappers that preserve the original function's parameter types. Instead of manually restating the types, use Parameters and the spread operator.

typescripttypescript
function logToServer(level: string, message: string, metadata?: object) {
  // sends log to remote server
}
 
function safeLog(...args: Parameters&lt;typeof logToServer&gt;) {
  try {
    logToServer(...args);
  } catch {
    console.error("Logging failed, but the application continues.");
  }
}

safeLog accepts exactly the same arguments as logToServer. If logToServer gains a new parameter, safeLog picks it up automatically. The compiler enforces that the call to logToServer inside the wrapper passes the arguments correctly.

This pattern is common in decorators, middleware, and any code that intercepts or augments function calls.

Parameters for dependency injection

Another common pattern is separating a function's dependencies from its call. Parameters lets you extract the argument types and use them elsewhere.

typescripttypescript
function renderPage(user: { name: string; role: string }, theme: "light" | "dark") {
  return `Welcome, ${user.name}. Theme: ${theme}`;
}
 
type RenderArgs = Parameters<typeof renderPage>;
 
function prepareRenderArgs(): RenderArgs {
  const user = { name: "Ada", role: "admin" };
  const theme = "dark" as const;
  return [user, theme];
}
 
renderPage(...prepareRenderArgs());

prepareRenderArgs returns a tuple that matches renderPage's parameter types exactly. The compiler checks that the returned array has the right length and each element has the right type.

Parameters with higher-order functions

Parameters works well with generics for building reusable function wrappers. A generic wrapper can take any function and return a new function with the same parameters.

typescripttypescript
function measureTime<F extends (...args: any[]) => any>(
  fn: F,
  label: string
): (...args: Parameters<F>) => ReturnType<F> {
  return (...args: Parameters<F>) => {
    const start = performance.now();
    const result = fn(...args);
    console.log(`${label} took ${performance.now() - start}ms`);
    return result;
  };
}

The wrapper's return type uses both Parameters and ReturnType utility type in TypeScript to produce a function that is identical to the original in type signature. Calling it with a plain add function gives full autocomplete and type checking on the result:

typescripttypescript
function add(a: number, b: number) { return a + b; }
const timedAdd = measureTime(add, "add");
 
timedAdd(3, 4);
// console: add took 0.05ms

Parameters vs writing the tuple by hand

For a function with one or two simple parameters, writing [string, number] by hand is fine. Parameters is more valuable when the function has many parameters, complex parameter types, or is likely to change.

ApproachGood forRisk
Write tuple by hand1 to 2 simple paramsDrifts when the function signature changes
Parameters<typeof fn>3+ params, complex typesNone. Always in sync

If the function signature changes, such as a parameter being added, removed, or retyped, the handwritten tuple stays stale until someone notices. Parameters updates immediately and the compiler catches mismatches.

Common mistakes

Using Parameters on a value instead of a type. Parameters&lt;saveToDatabase&gt; does not work. Always use Parameters&lt;typeof saveToDatabase&gt; to first get the function's type. This is the same pattern used with ReturnType. For more on typeof, see typeof type operator in TypeScript.

Expecting Parameters to work with overloaded functions predictably. Parameters extracts the parameters of the last overload signature, not the implementation. If your function has multiple overloads with different parameter lists, declare a separate type alias for the signature you need.

Forgetting that Parameters returns a tuple, not individual types. Parameters gives you a tuple like [string, number], not a union of string or number. To get individual parameter types, use indexed access: Parameters&lt;typeof fn&gt;[0] gives the type of the first parameter.

Rune AI

Rune AI

Key Insights

  • Parameters<T> extracts a function's parameter types as a tuple.
  • Combine it with typeof to capture the parameters of a specific function.
  • Use it to build wrapper functions that preserve the original parameter types.
  • For functions with no parameters, it returns an empty tuple [].
  • Like all utility types, Parameters exists only at compile time.
RunePowered by Rune AI

Frequently Asked Questions

What does Parameters return for a function with no parameters?

It returns an empty tuple `[]`. This is useful for conditional types or generic constraints that need to handle both parameterized and parameterless functions uniformly.

Does Parameters work with overloaded functions?

It extracts the parameters of the last overload signature. If you need a specific overload, declare a type alias for that signature and use Parameters on the alias.

Can I use Parameters to spread arguments into another function?

Yes. Parameters gives you a tuple type, and tuples can be spread. Pattern: `function wrapper(...args: Parameters&lt;typeof original&gt;)` captures the exact parameter types of the original function.

Conclusion

Parameters is the complement of ReturnType. Where ReturnType extracts what comes out of a function, Parameters extracts what goes in. Together they let you build higher-order functions and wrappers that stay perfectly in sync with their targets.