this jako typ

Typ this oznacza obiekt, na którym wywołano metodę, a parametr this opisuje kontekst zwykłej funkcji.

Na tej stronie

Przykład

#
TypeScript
class NotificationBuilder {
  protected parts: string[] = []

  title(text: string): this {
    this.parts.push(text.toUpperCase())
    return this
  }

  line(text: string): this {
    this.parts.push(text)
    return this
  }

  build(): string {
    return this.parts.join(' | ')
  }
}

class RewardNotification extends NotificationBuilder {
  exp(points: number): this {
    return this.line(`+${points} EXP`)
  }
}

const message = new RewardNotification().title('Zadanie ukończone').exp(20).line('Tak trzymaj!').build()
console.log(message)
Wynik
ZADANIE UKOŃCZONE | +20 EXP | Tak trzymaj!

Definicja i zastosowanie

#

W pozycji typu słowo this oznacza typ obiektu, na którym wywołano metodę. Metoda z typem zwracanym this zwraca więc nie klasę, w której ją napisano, ale klasę faktycznego obiektu. Dzięki temu łańcuch wywołań, np. builder.title(…).line(…), zachowuje metody klas pochodnych.

Drugie zastosowanie to parametr this: fikcyjny pierwszy parametr funkcji, np. function lessonLabel(this: Lesson, prefix: string). Nie przekazuje się go przy wywołaniu i znika po kompilacji. Kompilator sprawdza za to, czy funkcję wywołano z właściwym obiektem, na przykład przez call() albo jako metodę obiektu.

Typ this pojawia się też w predykatach metod (isDone(): this is DoneTask) i w interfejsach. Przy opcji noImplicitThis, która należy do trybu strict, użycie this w zwykłej funkcji bez opisanego typu kończy się błędem „'this' implicitly has type 'any' because it does not have a type annotation”.

Składnia

#
Składnia
class Klasa {
  metoda(): this {
    return this
  }
}

function nazwa(this: Typ, arg: string) { … }

Więcej przykładów

#
Metoda zwracająca klasę bazową
TypeScript
class PlainBuilder {
  line(text: string): PlainBuilder {
    return this
  }
}

class BadgeBuilder extends PlainBuilder {
  badge(name: string): BadgeBuilder {
    return this
  }
}

new BadgeBuilder().line('Brawo').badge('Seria 7 dni')
// Błąd: Property 'badge' does not exist on type 'PlainBuilder'.
Parametr this
TypeScript
interface Lesson {
  title: string
  minutes: number
}

function lessonLabel(this: Lesson, prefix: string): string {
  return `${prefix} ${this.title} (${this.minutes} min)`
}

const flexbox: Lesson = { title: 'Flexbox', minutes: 14 }
console.log(lessonLabel.call(flexbox, 'Lekcja:'))

const grid = { title: 'Grid', minutes: 16, label: lessonLabel }
console.log(grid.label('Moduł:'))

// lessonLabel('Lekcja:')
// Błąd: The 'this' context of type 'void' is not assignable to method's 'this' of type 'Lesson'.
Wynik
Lekcja: Flexbox (14 min)
Moduł: Grid (16 min)

Dobre praktyki

#
  • Metody do łańcuchowania, które kończą się return this, typuj jako : this, a nie nazwą klasy. Klasy pochodne nie stracą wtedy swoich metod w środku łańcucha.
  • Parametr this musi stać na początku listy i nie liczy się jako argument. Funkcje strzałkowe nie mają własnego this, więc nie mogą go deklarować: kompilator zgłosi „An arrow function cannot have a 'this' parameter”.
  • Osobno zadeklarowaną obsługę zdarzenia, która korzysta z this, opisz parametrem: function onClick(this: HTMLButtonElement). W trybie strict bez tej adnotacji użycie this jest błędem.

Powiązane hasła

#

Widzisz błąd albo brakuje przykładu? Napisz do nas.