Spis treści
- Używanie asercji w TS
- Przykład asercji
- Przykład często popełnianego błędu
- Jak powinno wyglądać poprawne zabezpieczenie?
Używanie asercji w TS
Asercja i rzutowanie typów to wyrażenia stosowane w branży zamiennie. Dziś, na potrzeby tego artykułu, używamy wyłącznie pierwszej frazy.
Kojarzysz sytuację, gdzie na początku deklarujesz jakiś typ, później chcesz skorzystać z niego w jakiś inny sposób, ale jesteś pewien, że wiesz, co robisz? Kompilatorowi zadeklarowało się co innego, więc trzeba go przekonać, że ma się rację. I tu właśnie na pomoc przychodzi nam asercja.
Przykład asercji
const value: unknown = 32;
const sampleNumber: number = 64;
const numberLength = (value as string).length
const total = (value as number) + sampleNumber;
W tej sytuacji wskazaliśmy kompilatorowi, że ma rzutować zmienną value
jako string
, ponieważ chcemy się dowiedzieć, z ilu cyfr składa się liczba. Właściwość length
nie jest dostępna na typie number
, ale asercja pozwala nam na prawidłowe jej użycie poprzez rzutowanie typu.
Drugi przykład to rzutowanie, że value
jest liczbą w celu umożliwienia dodania do siebie dwóch wartości.
Oczywiście są to bardzo proste i abstrakcyjne przykłady, ale one mają na celu pokazanie tylko w jaki sposób można użyć asercji! W rzeczywistości mogą być to mniej banalne sytuacje.
Przykład często popełnianego błędu
export default class SampleClass {
constructor(private readonly container: HTMLElement) {
this.slider = this.container.querySelector('.slider') as HTMLElement
/* code */
}
}
Dlaczego to jest błędem?
Ponieważ element może nie istnieć, a wtedy zwróci NULL
.
Przez asercję kompilator nie wyrzuci nam komunikatu o tym, że dany element może nie istnieć, przez co nie zabezpieczymy odpowiednio aplikacji przed błędami! Ponieważ asercja „oszuka” kompilator, że zawsze tam pojawi nam się jakiś element DOM’u
w tym przypadku (tutaj rzutowaliśmy ogólnie, że będzie to element HTML), a to nieprawda, bo może w jakimś wariancie lub błędzie zostać usunięty i zwrócić NULL
.
Jak powinno wyglądać poprawne zabezpieczenie?
export default class SampleClass {
slider: HTMLElement | null
constructor(private readonly container: HTMLElement) {
this.slider = this.container.querySelector('.slider')
if (!this.slider) return
/* code */
}
}
W wyżej pokazanym kodzie mamy prosty przykład tego, jak powinno to wyglądać. Dzięki czemu mamy pewność, że nasza aplikacja jest zabezpieczona. Teraz jawnie wskazujemy dwa możliwe typy, albo jest to element DOM’u
(jeśli istnieje oczywiście), albo NULL
w przypadku gdy element nie został pobrany (nie istnieje w danym momencie).
Dzięki tego typu zabezpieczeniu TS poinformuje nas „Ej, ej, mordeczko jest szansa, że this.slider jest null i co wtedy? Jak mam wykonać operację skoro nie ma wymaganego elementu?”. I tu wchodzimy MY – DEVELOPERZY i mówimy „Spoko, spoko, już przerywamy wykonywanie programu”. I dzięki temu nasza aplikacja jest bezpieczniejsza!