this în funcții în TypeScript

Funcții TypeScript 2.0

Primul parametru numit this declară pe ce obiect trebuie apelată funcția; tsc verifică apelurile.

Sintaxă
function f(this: Tip, a: number) { ... }
metoda(this: Clasa) { ... }

Ce face this în funcții

În JavaScript, this depinde de felul în care este apelată funcția: obiect.metoda() are this = obiect, dar aceeași funcție pusă într-o variabilă și apelată singură are this nedefinit. Asta este o sursă clasică de erori.

TypeScript permite un parametru this fals, pus primul: function f(this: Elev). Nu este un argument real (dispare la compilare), ci o promisiune: funcția trebuie apelată pe un Elev. tsc verifică apoi fiecare apel. În modul strict, opțiunea noImplicitThis dă eroare când this ar avea tipul any.

Pentru callback-uri în clase, cea mai simplă soluție este o funcție săgeată, care păstrează this-ul din jur. Tipurile utilitare ThisParameterType și OmitThisParameter lucrează cu acest parametru.

Exemple

Exemplul 1: Funcție care cere un anumit this

interface Elev {
    nume: string;
    note: number[];
}

function medie(this: Elev): string {
    const m = this.note.reduce((s, n) => s + n, 0) / this.note.length;
    return `${this.nume}: ${m.toFixed(2)}`;
}

const ana: Elev = { nume: "Ana", note: [9, 10] };
console.log(medie.call(ana));

const mihai = { nume: "Mihai", note: [7, 8, 6], medie };
console.log(mihai.medie());

Rezultat

Ana: 9.50
Mihai: 7.00

Exemplul 2: Apel fără obiect

interface Elev {
    nume: string;
}
function salut(this: Elev) {
    return `Salut, ${this.nume}`;
}
console.log(salut());

Eroarea afișată de tsc

exemplu.mts(7,13): error TS2684: The 'this' context of type 'void' is not assignable to method's 'this' of type 'Elev'.

Exemplul 3: Arrow function păstrează this în clasă

Metoda porneste dă un callback lui forEach. Funcția săgeată vede this-ul clasei.

class Catalog {
    elevi = ["Ana", "Mihai"];
    prefix = "Elev:";

    afiseaza(): void {
        this.elevi.forEach((nume) => console.log(this.prefix, nume));
    }
}

new Catalog().afiseaza();

Rezultat

Elev: Ana
Elev: Mihai

Greșeli frecvente

  • Dai o metodă ca callback (buton.onclick = obiect.metoda) și pierzi this. Folosește o funcție săgeată sau .bind(obiect).
  • Pui parametrul this într-o funcție săgeată. Nu este permis: funcțiile săgeată nu au this propriu.

Comenzi înrudite

  • arrow functions cu tipuri: Funcțiile săgeată primesc tipuri ca orice funcție; în callback-uri, tipul parametrilor se deduce din context.
  • class: Clasele din JavaScript, cu tipuri pe câmpuri, constructor și metode, plus modificatori de acces și interfețe.
  • ThisParameterType: ThisParameterType<F> dă tipul parametrului this al unei funcții; OmitThisParameter<F> îl elimină.
  • funcții cu tipuri: Pui tipuri pe parametrii și pe rezultatul funcțiilor; fiecare apel este verificat la compilare.