microsoft / microsoft/TypeScript

Inconsistent `typeof this` when the `this` parameter declared in the signature of a function parameter

Open
#63,616 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Bug Domain: This-Typing
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

https://www.typescriptlang.org/play/?ts=6.0.3#code/JYOwLgpgTgZghgYwgAgILIN7LgLmQZzClAHNkBfAKEo0uWQHoHlRJZEUAhTZEgCjAALYPjyoAlHgBuAe2AATCnUbMAesgDKqALIBRZAAUASgHlOAGV3blraPCTJuWEngHDRaccgC8APmSyCkrKMACuIAhgwDIgyDB8APp4nJIBcooYVCF8tPT0-F65efRgAJ4ADigAGj7IZZUyMHXuysVMeercfPiCMqEANooARigSrUr05OLU9PFF+XyF4yUtxSUV1bX1EI3NIssqHWjjVJPT2fO8i5gH28g13nUbu0L7a4f06qi3q3mnFNMskUwhEojE4olXK8PBIfP5AvJUgjMFlZnwQZForECjc2swACobZDQKAyKCuABMADYABwAZi8AHJoYyWABbcr9YAIYBgfqlZCCOD4J6VZCMuAgUqskYIOChfAoXnIeQyCAikAyMCCuBSFBwUX6kCasBwMEgAB043aAAEwPgALQQAAelUiTqgpKg4zuD0NL1+UxmEIx5quS2K0J9RL92wDbzy7U+xzOwfioax4dxeV9W2eTSjeKO30jgcBlCAA

💻 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

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.