OmitThisParameter<Type>

Produces the function type left after binding, with the explicit this parameter removed.

Signature
type OmitThisParameter<T> = unknown extends ThisParameterType<T> ? T : T extends (...args: infer A) => infer R ? (...args: A) => R : T;
  • Added in TypeScript 3.3

Parameters

ParameterTypeDescription
$Tany typeA function type, normally `typeof someFunction`. Generics are erased and only the last overload signature is carried over.

Return value

(...args: A) => R — the same signature without the `this` parameterA function type with the same parameters and return type but no `this` parameter. If `T` declares no `this` parameter, `T` is returned unchanged.

Errors

Nothing — a type with no `this` parameter passes through untouched rather than erroring.

Calling .bind() on a function that declares this: Something produces a new function that no longer needs a receiver. OmitThisParameter is the type of that result: same parameters, same return type, this requirement gone.

You reach for it at the boundary where a method stops being a method. Once you hand a bound function to map, an event emitter, a timer, or a React prop, the consumer must not be told it needs a context — it will never supply one. Annotating the bound value as OmitThisParameter<typeof method> states exactly that, and it is also the right return type for your own bindTo(ctx, fn) helper.

What trips people up

  • Generics are erased. Feed it a generic function and you get back the signature with the type parameters instantiated away, not a still-generic function type.
  • Only the last overload survives. An overloaded function loses every signature but the final one, which is rarely the one you meant.
  • It removes only the this parameter — bound leading arguments are not removed. fn.bind(ctx, arg1) produces a shorter signature than this utility describes; TypeScript's own bind overloads handle that case.
  • If the function never declared this, the utility is a no-op, so applying it defensively is harmless.

Example

Try it yourself
Loading editor…
Press Run to execute the code.

When to use it

  • Type the field that stores a method already bound to its instance.
  • Give a `bindTo(ctx, fn)` helper an honest return type.
  • Hand a context-dependent function to a callback API that will call it with no receiver.

Frequently asked questions

What type does bind return for a function with a this parameter?

`OmitThisParameter<typeof fn>` — the same parameters and return type with the `this` requirement dropped. Annotate the bound value with it so consumers see a plain callable.

Does OmitThisParameter also remove arguments passed to bind?

No. It removes only the `this` parameter; partially applied arguments are not accounted for. TypeScript's built-in `bind` overloads handle argument binding, so let inference do the work when you pass extra arguments.

What happens if the function has overloads or generics?

Both are lost: generics are erased and only the last overload signature is propagated into the resulting type. If you need those preserved, declare the bound function's type by hand.

More examples

A typed bind helper

`ThisParameterType` types the context going in and `OmitThisParameter` types the function coming out, so `greetAda` is `(punctuation: string) => string` — usable directly as a `map` callback. Output: `[ 'Hello, Ada!', 'Hello, Ada?' ]` then `Hello, Grace.`

Example · typescript
function greet(this: { name: string }, punctuation: string): string {
  return `Hello, ${this.name}${punctuation}`;
}

function bindTo<F extends (...args: any) => any>(
  ctx: ThisParameterType<F>,
  fn: F,
): OmitThisParameter<F> {
  return fn.bind(ctx) as OmitThisParameter<F>;
}

const greetAda = bindTo({ name: "Ada" }, greet);
const greetGrace = bindTo({ name: "Grace" }, greet);

console.log(["!", "?"].map((p) => greetAda(p)));
console.log(greetGrace("."));
// greetAda.call({ name: "Someone" }, "!"); // context is already fixed

Storing pre-bound handlers on an object

`c.tick` can be dropped into an array of plain callbacks because its type no longer mentions a receiver, yet it still mutates the right instance. The output is `5 10`: two calls through the array, then one direct call.

Example · typescript
function onTick(this: { count: number }, amount: number) {
  this.count += amount;
  return this.count;
}

class Counter {
  count = 0;
  readonly tick: OmitThisParameter<typeof onTick> = onTick.bind(this);
}

const c = new Counter();
const handlers: Array<(n: number) => number> = [c.tick];

handlers[0](2);
handlers[0](3);
console.log(c.count, c.tick(5));

Discussion

  • Be the first to comment on this lesson.