Adnotacje typów w TypeScript to sposób, w jaki programista może jawnie określić, jakiego rodzaju wartości oczekuje w zmiennych, funkcjach, obiektach, tablicach czy klasach. Dzięki adnotacjom typów kompilator TypeScript wie, jakie dane są przypisane do poszczególnych elementów programu, co umożliwia wcześniejsze wykrywanie błędów i zapewnia lepszą kontrolę nad kodem.
Przykłady adnotacji typów dla zmiennych:
const apples: number = 5;
let speed: string = 'fast';
let hasName: boolean = true;
let nothingMuch: null = null;
let nothing: undefined = undefined;
W powyższych przykładach każda zmienna ma przypisany typ (number, string, boolean, null, undefined), co ułatwia przewidywanie, jakie wartości mogą być przechowywane w zmiennych. Takie przypisanie pomaga w uniknięciu błędów typu „niespodziewana wartość” w czasie wykonywania programu.
Adnotacje typów wbudowanych obiektów (np. Date):
let now: Date = new Date();Zmienna now jest typu Date i oczekuje wartości będącej instancją klasy Date. Dzięki temu mamy pewność, że now będzie przechowywać datę i możemy korzystać z metod dostępnych dla tego typu obiektu, takich jak toLocaleDateString() czy getFullYear().
Definicja i podstawy inferencji typów (Type Inference)
Inferencja typów to proces, w którym TypeScript automatycznie określa typ zmiennej, funkcji czy obiektu na podstawie przypisanej do nich wartości. Jeśli nie użyjemy jawnych adnotacji typów, TypeScript spróbuje samodzielnie odgadnąć, z jakim typem ma do czynienia.
Przykład inferencji typów:
let count = 10; // TypeScript automatycznie przypisze typ `number`
let message = "Hello!"; // TypeScript przypisze typ `string`W powyższych przypadkach kompilator samodzielnie rozpoznaje typ number i string na podstawie przypisanych wartości. Dzięki inferencji programista nie musi ręcznie przypisywać typów, co sprawia, że kod staje się bardziej przejrzysty.
Różnice między adnotacjami typów a inferencją typów
- Adnotacje typów (Type Annotations):
- Są dodawane ręcznie przez programistę.
- Przydatne w sytuacjach, gdy typ wartości nie jest jednoznaczny lub kiedy chcemy mieć pełną kontrolę nad typami w kodzie.
- Pomagają w sytuacjach, gdy wartość zmiennej może zmieniać się w zależności od warunków (np.
stringlubnull).
- Inferencja typów (Type Inference):
- Działa automatycznie, bez konieczności ręcznego określania typu.
- Idealna do prostych przypisań, gdy typ jest oczywisty i jednoznaczny.
- Ułatwia pisanie kodu, zmniejszając ilość deklaracji typów.
Przykłady zastosowania adnotacji i inferencji typów
Adnotacje typów dla zmiennych:
let speed: string = "fast";
let age: number = 25;Wartości przypisane zmiennym mają jawnie określone typy, co wyraźnie komunikuje ich przeznaczenie.
Inferencja typów dla zmiennych:
let color = "blue"; // Kompilator przypisze typ `string`
let amount = 500; // Kompilator przypisze typ `number`
Adnotacje typów w funkcjach:
const logNumber: (i: number) => void = (i: number) => {
console.log(i);
};Adnotacje określają, że funkcja logNumber przyjmuje argument i typu number i nie zwraca żadnej wartości (void).
Inferencja typów w funkcjach:
function greet(name: string) {
return `Hello, ${name}`;
}TypeScript automatycznie przypisze typ string dla zwracanej wartości, ponieważ name ma typ string.
Zastosowanie adnotacji typów dla obiektów
Adnotacje typów są szczególnie przydatne przy definiowaniu struktury obiektów, co zapewnia przejrzystość i jednoznaczność danych:
let point: { x: number; y: number } = {
x: 10,
y: 20
};
W powyższym przykładzie obiekt point ma zdefiniowane dwie właściwości: x i y typu number.
Różnica między null a undefined
null i undefined to specjalne typy używane do oznaczenia braku wartości, ale mają różne znaczenie:
null:
- Oznacza celowy brak wartości.
- Programista musi przypisać
nulljawnie do zmiennej. - Przykład:
let user: string | null = null;
- Zmienna
usermoże przyjmować wartośćstringlubnull. Użycienulloznacza, że brak wartości jest świadomym wyborem.
undefined:
- Oznacza brak przypisanej wartości. Jest to domyślna wartość zmiennej, która została zadeklarowana, ale jeszcze nie została zainicjowana.
- Przykład:
let username: string | undefined;
console.log(username); // undefined
Przykłady użycia null i undefined
Zmienna z wartością null:
let currentUser: string | null = "Anna";
currentUser = null; // Użytkownik wylogowany, brak aktywnego użytkownika
console.log(currentUser); // Wydrukuje: nullZmienna z wartością undefined:
let pendingUser: string | undefined;
console.log(pendingUser); // Wydrukuje: undefined
Dlaczego przypisujemy undefined = undefined; null = null?
Przypisanie undefined do undefined i null do null może wydawać się redundantne, ale ma swoje uzasadnienie:
- Jawne określenie typu:
- Gdy przypisujemy
nulldo zmiennejnothingMuch, jasno komunikujemy, żenothingMuchjest zmienną, która przechowuje wyłącznienulli nie może przechowywać żadnej innej wartości. - Przypisanie
undefineddoundefinedwskazuje, że zmienna może przyjmować wartośćundefined, co jest przydatne, gdy chcemy pokazać, że zmienna jeszcze nie ma przypisanej wartości, ale oczekujemy jej późniejszego zainicjowania.
- Gdy przypisujemy
- Komunikacja w zespole:
- Jawne przypisanie
nulllubundefinedjest sposobem komunikacji między programistami. Wskazuje, że brak wartości jest zamierzony (null) lub że wartość zmiennej jest jeszcze nieustalona (undefined).
- Jawne przypisanie
- Eliminacja niejasności:
- Przypisanie
null = nulllubundefined = undefinedeliminuje wszelkie niejasności i pomaga w uniknięciu błędów logicznych, ponieważ wartości te są explicite określone.
- Przypisanie
Kiedy używać null, a kiedy undefined?
Używaj null, gdy:
Chcesz zasygnalizować, że zmienna powinna być pusta, np. w celu wyczyszczenia wartości:
let activeUser: string | null = "Jan";
activeUser = null; // Wylogowanie użytkownika
Używaj undefined, gdy:
Zmienna jeszcze nie ma przypisanej wartości i oczekujesz jej późniejszego przypisania
let userRole: string | undefined;
userRole = "admin"; // Zainicjowanie zmiennej później w kodzie