this jako typ
Typ this oznacza obiekt, na którym wywołano metodę, a parametr this opisuje kontekst zwykłej funkcji.
Przykład
#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)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
#class Klasa {
metoda(): this {
return this
}
}
function nazwa(this: Typ, arg: string) { … }Więcej przykładów
#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'.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'.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
thismusi stać na początku listy i nie liczy się jako argument. Funkcje strzałkowe nie mają własnegothis, 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 trybiestrictbez tej adnotacji użyciethisjest błędem.
Powiązane hasła
#- Typy funkcjiTypowanie parametrów, wartości zwracanej i samych funkcji jako wartości.
- Strażnicy typów (value is T)Własne funkcje sprawdzające, które zawężają typ w miejscu wywołania.
- public, private, protectedModyfikatory dostępu określające, skąd można używać pól i metod klasy.
- abstract classKlasa bazowa, której nie można utworzyć bezpośrednio, z metodami do uzupełnienia przez potomków.
- implementsDeklaracja, że klasa spełnia kontrakt opisany interfejsem.
Widzisz błąd albo brakuje przykładu? Napisz do nas.