Увійти Реєстрація
Блог Серії
Кар'єра
Вакансії Компанії
Навчання
Документація Співбесіди Тестування Відео
Екосистема
Пакети Ресурси Проєкти Інструменти Події
Інше
Про нас Реклама

Як типізувати this у функціях і методах TypeScript?

У JavaScript значення this залежить від способу виклику, а не від місця оголошення. TypeScript дає змогу описати очікуваний this - і перевірити, що функцію викликають правильно.

Параметр this - перший «фіктивний» параметр, який не існує під час виконання:

function disable(this: HTMLButtonElement, event: MouseEvent) {
  this.disabled = true;
}

button.addEventListener('click', disable);   // ок: this - кнопка

const handler = disable;
handler(new MouseEvent('click'));   // помилка: this має тип void, а не HTMLButtonElement

У скомпільованому JavaScript параметр this зникає.

Методи класів - TypeScript знає, що this - екземпляр класу. Але при «відриві» методу від об'єкта this губиться під час виконання:

class Counter {
  count = 0;
  increment() { this.count++; }
}

const c = new Counter();
const inc = c.increment;
inc();   // TypeError під час виконання: this - undefined

Рішення:

  • стрілкова функція як поле - this захоплюється при створенні: increment = () => { this.count++; }; (ціна - окрема функція на кожен екземпляр, і її немає в прототипі);
  • bind у конструкторі;
  • параметр this: Counter у методі - тоді TypeScript сам покаже помилку при виклику без об'єкта.

this як тип результату - для ланцюжків викликів, що коректно працюють у нащадках:

class QueryBuilder {
  where(column: string, value: unknown): this {
    // ...
    return this;
  }
}

class PostQuery extends QueryBuilder {
  published(): this { return this.where('status', 'published'); }
}

new PostQuery().where('id', 1).published();   // where повернув PostQuery, а не QueryBuilder

Тип-перевірка this is T - type guard для методів:

class Shape {
  isCircle(): this is Circle { return this instanceof Circle; }
}

ThisParameterType<F> і OmitThisParameter<F> - утиліти, щоб отримати або прибрати тип this з типу функції (корисно для обгорток над методами).

Докладніше в документації: Оголошення this у функції

Схожі питання