In TypeScript, what do the built-in `ThisParameterType<T>` and `OmitThisParameter<T>` utility types produce for a function type, and what are they for?
answer
- two utilities about the receiver
- extract it, or strip it
- unknown when none is declared
- signature of a bind-style wrapper
- Parameters<T> cannot reach it
basics
~20 sThisParameterType<T> extracts the declared receiver type of a function type, or unknown when it declares none. OmitThisParameter<T> returns the same function type with the receiver requirement removed, which is what a function looks like once a receiver has been supplied.
solid answer
~50 sThey are the two built-in utilities that operate on a function type's `this` parameter. `ThisParameterType<T>` pulls the receiver type out — for `type Greet = (this: { name: string }, msg: string) => string` it gives `{ name: string }` — and yields `unknown` when the function type declares no receiver. `OmitThisParameter<T>` strips the requirement, turning that `Greet` into `(msg: string) => string`, and returns `T` untouched when there was no `this` parameter to remove. The everyday use is writing helpers that pair a receiver-dependent function with its receiver: a wrapper can accept `fn: T` plus `context: ThisParameterType<T>` and hand back an `OmitThisParameter<T>` that is safe to pass around. The same shape describes what happens to a function type when its receiver is fixed. Both are erased like everything else — they describe function types, they do not bind anything.
code
typescript · 14 linestype Greet = (this: { name: string }, greeting: string) => string;
type Ctx = ThisParameterType<Greet>; // { name: string }
type Bare = OmitThisParameter<Greet>; // (greeting: string) => string
const greet: Greet = function (greeting) {
return `${greeting}, ${this.name}`;
};
const bound: Bare = greet.bind({ name: "Ada" });
console.log(bound("Hello")); // "Hello, Ada"
type NoReceiver = ThisParameterType<(n: number) => void>; // unknown
const check: NoReceiver = 42; // unknown accepts anythinggo deeper
Just recognise the two names and what each returns: one extracts the receiver type from a function type, the other removes the receiver requirement from it.
Be able to write the wrapper signature they exist for — fn plus a matching context in, a receiver-free function type out — and state the unknown fallback when no receiver is declared.
Show where they earn their place in infrastructure code: method wrappers that must preserve a signature, adapters between receiver-style and callback-style APIs, and be explicit that the type says nothing about whether your implementation really supplied a receiver.
Weigh whether receiver-typed function types belong in a shared codebase at all. Argue when preserving them through wrappers is worth the type gymnastics versus normalising the API so the receiver is an ordinary parameter.
## The pair TypeScript ships two utility types dedicated to the `this` parameter of a function type. They are ordinary conditional types defined in the standard library, so there is no magic to them beyond `infer`. - `ThisParameterType<T>` — the type of `T`'s `this` parameter, or `unknown` if `T` declares none. - `OmitThisParameter<T>` — `T` with the `this` parameter removed; `T` unchanged if there was none. ```ts type Greet = (this: { name: string }, greeting: string) => string; type Ctx = ThisParameterType<Greet>; // { name: string } type Bare = OmitThisParameter<Greet>; // (greeting: string) => string type None = ThisParameterType<(n: number) => void>; // unknown ``` Notice the `unknown` fallback rather than `never` or `any`: `unknown` is the honest answer for "there is no constraint here", and it is also what `OmitThisParameter` tests against to decide whether it has anything to do. ## Why the extraction is useful A function type with a `this` parameter carries two pieces of information that ordinary utilities cannot reach. `Parameters<T>` deliberately skips the receiver, and `ReturnType<T>` says nothing about it. So without these two utilities there is no way to write a generic helper that talks about the receiver at all. The canonical use is a helper that supplies a receiver: ```ts function withContext<T extends (this: any, ...args: any[]) => any>( fn: T, context: ThisParameterType<T>, ): OmitThisParameter<T> { return fn.bind(context) as OmitThisParameter<T>; } ``` The signature reads exactly like the transformation it performs: take something that demands a receiver, take a matching receiver, give back something that no longer demands one and is therefore safe to hand to any caller. That "no longer demands one" is the whole point — a callback consumer that expects a plain function will accept the result. ## The relationship to the standard library's own declarations The same idea appears inside the standard library's typing of function methods. Under `strictBindCallApply`, `call`, `apply` and `bind` are declared through interfaces that use the function's own `this` type: the receiver you pass is checked against what the function declared, and `bind` produces a function type without the requirement. So `OmitThisParameter` is describing a transformation the library already models for the built-in case; you reach for the utility when you are writing your own wrapper rather than calling `bind` directly. ## Where they show up in real code They are niche — most application code never needs them. You meet them when writing infrastructure: decorator-ish wrappers that log or memoize a method and must preserve its signature, adapters between a receiver-style API and a callback-style one, and typed helpers for older libraries whose declarations use `this` parameters. Their appearance in an interview is usually a probe of whether the candidate understands that a `this` parameter is a *part of a function type* that can be inspected and transformed like any other part. ## Limits worth stating Both are pure type-level operations. `OmitThisParameter<T>` does not bind anything — it describes a function type, and it is your runtime code (a `bind`, a closure, an explicit call form) that must actually supply the receiver. If your implementation returns the function unchanged while the type claims the receiver requirement is gone, the type layer will happily let callers detach it and the failure surfaces at runtime. As with every part of the type system, these utilities are erased; nothing survives compilation. A second limit: `ThisParameterType` gives you `unknown` for a function type with no `this` parameter, which is not the same as saying "any receiver is fine". If your helper needs to distinguish "declares no receiver" from "declares `this: void`", you have to test for it yourself with a conditional type, because the fallback flattens the first case into `unknown`.
- What does `ThisParameterType<T>` give you when `T` declares no `this` parameter, and why that type?It gives `unknown`. That is the accurate statement of "no constraint was declared" — unlike `any` it stays safe to use, and unlike `never` it does not falsely claim the position is uninhabitable. `OmitThisParameter<T>` uses exactly that fallback to detect the no-receiver case and return `T` unchanged.
- Why can't you just use `Parameters<T>` to get at the receiver type?`Parameters<T>` infers the rest-argument list, and a `this` parameter is deliberately not part of that list — it is a separate slot on the function type. So `Parameters` skips it entirely, and `ThisParameterType` exists precisely because there is otherwise no way to reach it.
saying these in an interview costs you the question
- Thinks OmitThisParameter binds the function at runtime
- Expects ThisParameterType to return any or never when none is declared
- Believes Parameters<T> includes the this parameter
- Assumes these utilities require experimentalDecorators or a flag