У 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 з типу функції (корисно для обгорток над методами).