W pierwszym wpisie wprowadzającym do języka TypeScript poruszyłem temat adnotacji typów zmiennych. Jak już wiemy jest to informacja dla TypeScriptu o tym jakiego typu jest nasza zmienna a dodajemy go po dwukropku za zmienną np.: `const color: string = red'. Opisana została także inferencja typów, która jest działaniem podjętym przez TypeScript w celu domyślenia się jaki typ powinna mieć zmienna przypisana i przypisanie jej go gdy nie posiada ona zadeklarowanej adnotacji.
Z tą krótką powtórką wiedzy możemy przejść do wykorzystywania tych rozwiązań podczas korzystania z funkcji.
const sumNumbers = (a: number, b: number): number => {
return a + b;
}
// w argumentach funkcji TS wymaga od nas podania typów
// za argumentami funkcji dodajemy także typ wartości przez nią zwracaną
Jak możemy zauważyć przy deklarowaniu funkcji podajemy typy argumentów przez nią przyjmowanych. Ten element jest wymagany przez język TypeScript. Inaczej wygląda typ wartości zwracanej przez funkcję. Informacja o tym nie musi być dopisana gdyż TS dzięki inferencji typów sam domyśli się jaki typ wartości dana funkcja ma zwrócić.
Dlaczego w zwracanej przez funkcji wartości zachodzi inferencja typów a pomimo to chcemy zawsze mieć zaznaczone to jaki typ zwróci dana funkcja? Po pierwsze sprawia, to że kod jest bardziej czytelny i w szybszy sposób możemy się domyślić jaką wartość możemy oczekiwać z funkcji.
Po drugie możemy zapobieć dzięki temu błędowi, który sprawi, że nasza funkcja nie będzie zwracała żadnej wartości a pomimo to TS nie wskaże nam tego błędu (gdyż nie będzie tego traktował jako błąd). Opisany błąd może nam się przydażyc gdy w naszej funkcji zapomnimy o słowie kluczowym return
.
Spowoduje to, że TS stwierdzi, że skoro nie chcemy nic zwracać w naszej funkcji a nie dodaliśmy adnotacji zwracanego typu to wszystko się zgadza (bo się zgadza - good guy TS).
Jak możemy zauważyć w funkcji nastąpiła inferencja typów, który został ustawiony na void.
Gdy jednak dodamy typ zwracanej wartości funkcji - zostanie wyświetlony błąd informujący o tym, że zwracana wartość jest typu void.
Co w przypadku gdy inaczej deklarujemy funkcję?
W kontekście deklarowania funkcji i określania typó argumentów oraz typu wartości zwracanej funkcji pokaże jezcze kilka przykładów, które opierają się na funkcjach innych niż strzałkowe.
Pierwszym przykładem jest funkcja deklarowana za pomocą słowa kluczowego function (named function). Nie różni się to zbytnio od przykładu z funkcją strzałkową.
function multiplyValue(a: number, b: number): number {
return a * b;
}
Kolejnym przykładem jest anonimowa funkcja, która przypisujemy do zmiennej.
const multiply = function(a: number, b:number): number {
return a * b;
}
Obydwu powyższym przykładom także dopisujemy adnotacje informującą jaki typ wartości zwracają.
Chciałbym przedstawić także dwa przykłady kiedy adnotacją naszej funkcji będze void lub never.
Gdy jedynym wynikiem naszej funkcji jest wyświetlenie informacji w konsoli wtedy zwracanym przez nią typem jest void.
const logStatus = (message: string): void => {
console.log(message);
}
Wartość o typie never zwracana jest wtedy gdy nasza funkcja - nic nie zwraca. Ten przypadek jest bardzo abstrakcyjny i raczej nie powinniśmy nigdy mieć potrzeby stworzenia takiego potworka.
const throwErr = (message: string): never => {
throw new Error(message);
}
W tym poście dodatkowo chciałbym opisać to w jaki sposób działa destrukturyzacja w TypeScript.
Jak wiemy w klasycznym JavaScript dzieje się to za pomocą użycia nawiasów klamrowych i wyciągniecię odpowiednich wartości z otrzymywanego obiektu.
// JavaScript
const car = {
color: 'red',
available: true,
cost: 190000,
}
const getCarColor = ({ color }) => console.log(`Car have ${color} color.`);
W przypadku TS podczas destrukturyzacji musimy określić także typ wartości.
// TypeScript
const car = {
color: 'red',
available: true,
cost: 190000,
}
const getCarColor = ({ color }: { color: string }) => console.log(`Car have ${color} color.`);
Podsumowanie
W tym poście to wszystko na temat wykorzystywania adnotacji w funkcjach TypeScriptowych. Utrwaliliśmy sobie dzięki temu wiedzę czym jest adnotacja, inferencja i jak z nich korzystać. Dodatkowo wiemy w jaki sposób destrukturyzować wartości otrzymywane w funkcjach.