# TypeScript `this` Typing

Handling `this` in JavaScript can be tricky because its value depends on how a function is called. TypeScript helps catch errors related to incorrect `this` usage by allowing you to explicitly type it.

## 1. The `noImplicitThis` Flag

To benefit from `this` checking, you should enable the `noImplicitThis` flag in your `tsconfig.json` (it is included in `strict: true`).

```json
{
  "compilerOptions": {
    "noImplicitThis": true
  }
}
```

When enabled, TypeScript will raise an error if `this` has an implied `any` type.

## 2. Explicit `this` Parameters

If you have a standalone function that expects to be called with a specific context, you can add a `this` parameter. It **must** be the first parameter in the function signature. TypeScript strips this parameter away during compilation; it exists only for type checking.

```typescript
interface User {
  id: number;
  username: string;
}

function printUser(this: User) {
  console.log(this.username);
}

const user: User = { id: 1, username: "Alice" };

// Usage
// printUser(); // Error: The 'this' context of type 'void' is not assignable...
printUser.call(user); // OK
```

## 3. `this` in Classes and Callbacks

A common issue in classes is passing a method as a callback, losing the `this` context.

```typescript
class Handler {
  info: string = "I am a handler";

  handleBad() {
    console.log(this.info);
  }

  handleGood = () => {
    console.log(this.info);
  }
}

const h = new Handler();
const cb1 = h.handleBad;
// cb1(); // Runtime Error: Cannot read property 'info' of undefined (or window)

const cb2 = h.handleGood;
cb2(); // OK: Arrow functions capture 'this' at creation time
```

## 4. Polymorphic `this` (Fluent Interfaces)

In classes, you can use `this` as a return type. This is useful for fluent APIs (method chaining), especially when inheritance is involved.

```typescript
class BasicCalculator {
  public constructor(protected value: number = 0) {}

  public currentValue(): number {
    return this.value;
  }

  public add(operand: number): this {
    this.value += operand;
    return this;
  }
}

class ScientificCalculator extends BasicCalculator {
  public sin(): this {
    this.value = Math.sin(this.value);
    return this;
  }
}

const v = new ScientificCalculator(2)
  .add(1)  // Returns 'this' (ScientificCalculator)
  .sin()   // Returns 'this' (ScientificCalculator)
  .add(5)  // Still works!
  .currentValue();
```

If `add` returned `BasicCalculator`, you couldn't call `.sin()` after `.add()`. Returning `this` ensures the type stays specific to the subclass.

[[programming/javascript/typescript/typescript]]