Как лучше сделать тип для колбэка с передачей в него this?

В TypeScript существует несколько способов задать тип для колбэка с передачей в него контекста (this).

1. Использование this типа в качестве параметра:

type CallbackFn = (this: SomeContextType, arg1: number, arg2: string) => void;

class SomeClass {
  private someProperty: number;
  
  constructor() {
    this.someProperty = 0;
  }
  
  public someMethod(callback: CallbackFn) {
    callback.call(this, 10, "hello");
  }
}

const context = {
  someMethod: function(arg1: number, arg2: string) {
    console.log(arg1 + this.someProperty, arg2);
  }
};

const instance = new SomeClass();
instance.someMethod(context.someMethod);

В этом примере CallbackFn определен как тип функции, принимающей два аргумента типов number и string, и не возвращающей значения. Параметр this в этом типе гарантирует, что при вызове колбэка через call или apply, this будет указывать на экземпляр SomeClass.

2. Использование объекта в качестве контекста колбэка:

interface CallbackContext {
  someProperty: number;
  callback: (arg1: number, arg2: string) => void;
}

class SomeClass {
  private someProperty: number;
  
  constructor() {
    this.someProperty = 0;
  }
  
  public someMethod(context: CallbackContext) {
    context.callback(10, "hello");
  }
}

const context = {
  someProperty: 20,
  callback: function(arg1: number, arg2: string) {
    console.log(arg1 + this.someProperty, arg2);
  }
};

const instance = new SomeClass();
instance.someMethod(context);

В этом примере тип CallbackContext определен как интерфейс со свойством someProperty типа number и методом callback, принимающим аргументы типов number и string и не возвращающим значения. Поэтому в методе someMethod можно непосредственно обращаться к колбэку через свойство объекта context, гарантируя, что контекст будет передан правильно.

Оба этих способа позволяют задать тип для колбэка с передачей this. Выбор способа зависит от контекста использования и предпочтений программиста.