microsoft / microsoft/TypeScript
Inconsistent `typeof this` when the `this` parameter declared in the signature of a function parameter
Nobody has claimed this yet.
- Dominant language
- Go
- Stars
- 111k
- Forks
- 14.3k
- Avg merge
- 2d 4h
- Merged PRs (30d)
- 132
Description
🔎 Search Terms
"this parameter", "typeof this"
🕗 Version & Regression Information
- This changed between versions 5.9.3 and 6.0.x
⏯ Playground Link
💻 Code
interface A { a: string }
{
// interface B { g(this: A): void }
// ^ SAME PROBLEM
interface B { g: (this: A) => void }
function f(_: B): void {}
f({
g() {
type X = typeof this
// ^ B (should be A)
}
})
f({
g() {
this
type X = typeof this
// ^ A
}
})
f({
g() {
type X = typeof this
// ^ A
this
}
})
}
{
function f(_: (this: A) => void): void {}
f(function g() {
// Type error: (2683) 'this' implicitly has type 'any' because it does not have a type annotation.
// @ts-expect-error
type X = typeof this
})
f(function g() {
this
type X = typeof this
// ^ A
})
f(function g() {
type X = typeof this
// ^ A
this
})
}
🙁 Actual behavior
When declaring the this parameter in the signature of a function parameter (e.g., a callback function like function f(callback: (this: A) => void): void {}), the inferred typeof this in the function body can be inconsistent. If this is used in the function body, typeof this behaves as expected. If this is not used, typeof this is inferred as if the this parameter was never declared in the signature.
🙂 Expected behavior
The inferred typeof this should be consistent regardless of the usage of this in the function body.
Additional information about the issue
I can reproduce this problem also in @typescript/native-preview: 7.0.0-dev.20260705.1.
Locally I used the "default" tsconfig.json (tsc --init/tsgo --init):
{
// Visit https://aka.ms/tsconfig to read more about this file
"compilerOptions": {
// Environment Settings
// See also https://aka.ms/tsconfig/module
"module": "nodenext",
"target": "esnext",
"types": [],
// Other Outputs
"sourceMap": true,
"declaration": true,
"declarationMap": true,
// Stricter Typechecking Options
"noUncheckedIndexedAccess": true,
"exactOptionalPropertyTypes": true,
// Recommended Options
"strict": true,
"jsx": "react-jsx",
"verbatimModuleSyntax": true,
"isolatedModules": true,
"noUncheckedSideEffectImports": true,
"moduleDetection": "force",
"skipLibCheck": true,
}
}
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the linked TypeScript Playground repro and compare behavior between 5.9.3 and 6.0.3, focusing on contextual typing of callback this parameters. Locate the compiler tests for this-type inference and add a regression case covering the three object-method examples and the standalone callback; done means typeof this consistently resolves to A without requiring a runtime this use.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- compilers
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 48/100