OmitThisParameter<Type>
Produces the function type left after binding, with the explicit this parameter removed.
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
| Parameter | Type | Description |
|---|---|---|
$T | any type | A 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
thisparameter — bound leading arguments are not removed.fn.bind(ctx, arg1)produces a shorter signature than this utility describes; TypeScript's ownbindoverloads handle that case. - If the function never declared
this, the utility is a no-op, so applying it defensively is harmless.
Example
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.`
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 fixedStoring 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.
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