TypeScript - podstawowe typy
Wraz z rosnącym wykorzystaniem TypeScripta, myślę, że nadszedł czas, aby zacząć się go uczyć. Czym jest? Po co go używać? Postaramy się odpowiedzieć na te pytania i nauczyć się kilkunastu podstawowych typów.
Ostatnia aktualizacja 5 marca 2023![Kłódka w kolorze morskim zamykająca niebieską bramkę](/static/ac0a2fde1c05605fe46c944a67d5f5e7/51e3c/maxim-zhgulev-5tmItJfHkIc-unsplash.jpg)
Niedawno zacząłem uczyć się TypeScripta (w zasadzie kodowałem wcześniej w Angularze, więc TypeScript nie jest dla mnie zupełnie nowy, ale od tamtej pory nie używałem go często). Na początku miałem wątpliwości, nie będę kłamał. Kod w tym języku wydawał mi się opasły i nieelegancki. Ale bądźmy szczerzy - jedynym minusem TypeScripta jest to, że musisz poświęcić czas na naukę. Jestem tylko człowiekiem, więc zmiana może być przerażająca. Ale jedyną stałą życiu jest zmiana. Zmiany mogą być dobre. A wraz z rosnącym wykorzystaniem TypeScripta, to jest dobry moment żeby zacząć się go uczyć. Ucz się ze mną!
Czym jest TypeScript?
U podstaw, TypeScript jest nadzbiorem JavaScriptu. Co to znaczy? Już wyjaśniam zagadnienie. Pewnie pamiętasz zbiory ze szkoły - wiesz, te przecinające się kółka. Jest to diagram Venna - graficzna reprezentacja, która pokazuje logiczne relacje pomiędzy tymi zbiorami. Podobna relacja zachodzi pomiędzy językiem JavaScript i TypeScript - TypeScript to nadzbiór JavaScriptu lub JavaScript to podzbiór TypeScripta. Każda linia kodu JS jest poprawnym kodem TS, ale nie odwrotnie.
To znaczy, że TypeScript rozbudowuje JavaScript. Dodaje nowe funkcjonalności i zalety względem “waniliowego” języka. W zasadzie, TypeScript to zarówno język jak i narzędzie. Jest to potężny kompilator, który uruchamiasz, żeby skompilować kod TS do JS. Dlaczego? Bo przeglądarki rozpoznają tylko kod JS.
Dlaczego używać TypeScripta?
W programowaniu chodzi o myślenie, a nie o pisanie.
“No dobra, po co pisać kod, którego przeglądarki nie rozpoznają?”. Istnieje kilka zalet.
- Przede wszystkim, TypeScript zmusza cię, abyś myślał więcej o swoim kodzie i celach. Wszystkie twoje intencje są spisane - nie ma miejsca na domysły.
- TypeScript dodaje nowe funkcjonalności - niedostępne w bazowym języku - jak np. interfejsy czy generyki.
- TypeScript oferuje meta-programistyczne funkcjonalności jak dekoratory.
- Dzięki krokowi kompilacji, możesz używać współczesnej składni języka JavaScript i nie przejmować się wsparciem dla przeglądarek. Jest to podobna zaleta jak w przypadku używania kompilatora Babel.
- Wiele opcji konfiguracji - możesz skonfigurować kompilator według swoich potrzeb.
- Jak nazwa wskazuje, oferuje on typy. Na nich skupimy się w następnych sekcjach.
- Lepsze autouzupełnianie w edytorach tekstu i IDE.
Typy JavaScript, a typy TypeScript
JavaScript jest dynamicznie typowanym językiem. Typy są ustalane w trakcie pracy skryptu. Ma to swoje zalety, ale może powodować wiele błędów.
TypeScript jest typowany statycznie. Definiujemy typy podczas rozwoju oprogramowania. Nie zmieniają się po uruchomieniu skryptu.
Typy TypeScript
Zacznijmy od tego, że TypeScript dostarcza dodatkowe typy do języka JavaScript. Istnieją typy które są dostępne zarówno w JavaScripcie jak i w TypeScripcie. Ale istnieją też typy dostarczone przez nasz nadzbiór.
Podstawowe typy dostępne w JS i TS to:
number
string
boolean
object
array
Dodatkowe typy oferowane przez TypeScript to m.in.:
Tuple
Enum
Any
Union
Literal
Custom
Przypisywanie typów
JavaScript nie rozumie składni przypisywania TypeScripta. Typy są używane przez kompilator TS. TypeScript ma wbudowaną funkcjonalność nazwaną wnioskowaniem typu. TS robi co może, aby zrozumieć typ konkretnej zmiennej lub stałej. Dlatego nie musisz ich ręcznie deklarować za każdym razem. Aby przypisać typ do zmiennej możesz wykorzystać dwukropek.
TYPESCRIPT
1let name: string // Zmienna name ma typ string.
Wszystkie podstawowe typy w TypeScripcie są zapisane z małej litery.
Number
Podobnie do bazowego języka, TypeScript nie definiuje różnych typów liczb. Liczby w JavaScript są zapisywane zawsze jako liczby zmiennoprzecinkowe podwójnej precyzji, zgodne ze standardem IEEE 754 lub jako big integers.
TYPESCRIPT
1const PI = 3.14 // TypeScript wnioskuje, że ta liczba zawsze powinna równać się 3.14.2let age = 25 // TypeScript wnioskuje, że to ma być liczba.3// W przypadku maksymalnego wieku dziewczyny DiCaprio to równiez jest stała - wiem.4let age: number = 25 // Ten kod działa ale jest redundantny - zła praktyka.5let age: number // Tu ma to sens, ponieważ nie ma inicjalizacji zmiennej.
String
Aby zdefiniować string, użyj cudzysłowów podwójnych lub pojedynczych. Template strings, wykorzystując odwrotny apostrof, też są opcją.
TYPESCRIPT
1const maxim = "Medals don't help me sleep at night." // TypeScript wnioskuje, że ten string jest stały.2let name = "Sam" // TypeScript wnioskuje, że powinien być to typ string.3let name: string // Tej zmiennej będzie przypisany string.
Boolean
Najbardziej podstawowy typ danych - reprezentuje wartość true lub false. W przeciwieństwie to JavaScriptu, TypeScript nie posiada wartości “truthy” i “falsy”.
TYPESCRIPT
1let isDone: boolean
Object
Typ obiektu definiujesz podobnie do standardowych obiektów JS. Jednakże zamiast par klucz-wartość, zapisujesz pary klucz-typ. Przyjrzyj się składni - odrobinę się różni.
TYPESCRIPT
1const person = {2 name: "Sam",3 age: 66,4}56// TypeScript wnioskuje.7const person: {8 name: string9 age: number10}1112// Tak możesz definiować generyczne obiekty.13const person: object = {14 name: "Sam",15 age: 66,16}1718// Możesz także zdefiniować bardziej konkretną strukturę obiektu.19const person: { name: string } = {20 name: "Sam",21 age: 66, // Tej właściwości nie ma w typie, więc powoduje błędy.22}
Array
W języku JavaScript, możesz mieszać różne typy danych - jedna tablica może składać się z liczb i łańcuchów znaków. Każda tablica JS jest poprawną tablicą TS. Tablice TS mogą być elastyczne, ale również restrykcyjne.
TYPESCRIPT
1const person = {2 hobbies: ["Krav maga", "sneaking"],3}45// TypeScript wnioskuje.6const person: {7 hobbies: string[]8}910// Możesz zdefiniować restrykcyjna tablicę zawierającą tylko łańcuchy znaków.11let hobbies: string[]1213// Możesz także zdefiniować bardziej elastyczną tablicę.14let hobbies: any[]
Tuple
Typ tuple nie jest dostępny w języku JavaScript - jest dodany przez TypeScript. Tuple to tablica o stałej długości i typie. Może być przydatna, gdy wcześniej znasz dokładną strukturę tablicy.
TYPESCRIPT
1const person = {2 role: [3, "agent"],3}45// TypeScript wnioskuje.6const person: {7 role: (string | number)[]8}910// Możesz wyraźnie zdefiniować strukturę typu tuple.11const person: {12 role: [number, string]13} = {14 role: [3, "agent"],15}
Enum
Enum to niestandardowy typ w języku TypeScript. Daje ci wyliczoną listę. Typ enum mapuje czytelne dla człowieka etykiety do liczb, zaczynając od 0. Nie jest dostępny w JavaScripcie i zostaje skompilowany do IIFE.
TYPESCRIPT
1// Etykiety są często zapisane wielkimi literami.2enum Role {3 AGENT,4 INTEL,5}67const person = {8 role: Role.AGENT,9}1011// Możesz zmienić domyślne zachowanie typu enum.12enum Role {13 AGENT = "AGENT",14 INTEL,15}
Union
Czasami chcesz akceptować więcej niż jeden rodzaj wartości. W takiej sytuacji przydaje się typ union. Możesz zdefiniować unie wykorzystując znak poziomej kreski pomiędzy różnymi typami.
TYPESCRIPT
1// Oba parametry tej funkcji mogą być zrówno liczbą jak i ciągiem znaków.2function combine(i1: number | string, i2: number | string) {3 const result = i1 + i24 return result5}
Literal
Wspomniałem o tym typie w poprzednich fragmentach kodu, ale czas zdefiniować go oddzielnie. Typ literal nie określa tylko typu zmiennej, ale także mówi: “ta zmienna powinna otrzymać tę konkretną wartość”.
TYPESCRIPT
1const PI = 3.14 // TypeScript oczekuje tej konkretnej liczby, nie dowolnej liczby.23function combine(4 i1: number | string,5 i2: number | string6 // Union połączone z typem literal - tylko dwa możliwe łańcuchy znaków.7 conversion: "as-text" | "as-number"8) {9 const result = i1 + i210 return result11}
Custom
Poza wbudowanymi typami, TypeScript pozwala ci także definiować niestandardowe typy (znane także jako aliasy typów). Istnieje specjalne słowo kluczowe - type
- do tego celu. Możesz wrzucić cokolwiek do niestandardowego typu: sting, obiekt czy unie. Po zdefiniowaniu niestandardowego typu, możesz użyć tego aliasu w wielu miejscach w kodzie. W ten sposób unikasz duplikacji kodu.
TYPESCRIPT
1// Konwencja mówi, żeby definować niestadardowe typy z wielkiej litery.2type State = "idle" | "loading" | "success"34type Person = {5 name: string6 age: number7}
Możesz wykorzystać dowolną nazwę dla niestandardowego typu, ale nie możesz wykorzystać zarezerwowanych słów kluczowych języka JavaScript (lub TypeScript) jak Date
czy Math
.
Typy parametrów funkcji
W poprzednich fragmentach kodu, ustawiałem typy parametrom funkcji. Możesz je dodawać po każdym parametrze wykorzystując standardową składnię.
TYPESCRIPT
1// Funkcja ma dwa parametry, gdzie każdy z nich to liczba.2function add(n1: number, n2: number) {3 return n1 + n24}
Typy zwracane przez funkcję
Podobnie możesz ustawiać typy wartościom zwracanym przez funkcje. void
jest często używany z funkcjami, które nie zwracają żadnej wartości. Jest jak przeciwieństwo typu any
- brak jakiejkolwiek wartości.
TYPESCRIPT
1function add(n1: number, n2: number) {2 return n1 + n23}45// TypeScript wnioskuje.6function add(n1: number, n2: number): number {7 return n1 + n28}910// Możesz wyraźnie zaznaczyć typ zwracanej wartości11// ale w większości wypadków TypeScript może go wywnioskować.12function add(n1: number, n2: number): string {13 return n1.toString() + n2.toString()14}1516// Możesz użyć typu void17// jeżeli funkcja nie zwaraca wartości.18function printResult(num): void {19 console.log("Result: " + num)20}2122// Undefined to poprawny typ w TypeScript,23// ale nie gdy funkcja niczego nie zwraca.24function printResult(num: number): undefined {25 console.log("Result: " + num)26}
Wyrażenie typu funkcji
Istnieje także typ Function
w języku TypeScript. Opisuje on właściwości takie jak bind
lub apply
- dostępne we wszystkich funkcjach w JavaScripcie. Jednakże, deklarowanie niespecyficznej funkcji nie jest zbyt przydatne. Lepszym sposobem na ich opisywanie jest wyrażenie typu funkcji. Jeżeli przypomina ci funkcje strzałkowe - masz rację - składnia jest podobna.
TYPESCRIPT
1// Deklarowanie niespecyficznej funkcji.2let combineValues: Function34// Ta funkcja przyjmuje dwa parametry, gdzie każdy z nich to liczba.5// Funcja ogólnie zwaraca liczbę.6let combineValues: (a: number, b: number) => number
Unknown
Istnieje inny nieznany dla nas typ (hehe). Jest podobny do typu any
, ale jest bezpieczniejszy. Nie możesz zrobić czegokolwiek z typem unknown
.
TYPESCRIPT
1let input: unknown2let name: string34input = 55name = "Sam"6// To nie zadziała, ponieważ nie ma gwarancji,7// że typ unknown będzie stringiem.8name = input
TYPESCRIPT
1let input: any2let name: string34input = 55input = "Sam"6// Z drugiej strony, to zadziała, ponieważ7// typ any jest najbardziej elastyczny.8name = input
Never
Niektóre funkcje w JavaScripcie nigdy nie zwracają wartości. “Chwila, moment, czym się to różni od typu void
?”. Musimy zagłębić się w język JavaScript, aby odpowiedzieć na to pytanie.
Funkcja, w której nie ma wyrażenia return, nadal zwraca undefined
w języku JavaScript. Mogłeś zaobserwować to zachowanie przy funkcjach, które logują coś w konsoli. Pomimo że ignorujemy tę wartość, ona tam nadal jest. Jest to dobre miejsce na wykorzystanie typu void
.
Funkcja która ma przypisany typ never
, nigdy nie zwraca wartości. Nie zwraca nawet domyślnego undefined
. Taka sytuacja zachodzi, gdy funkcja wyrzuca error.
TYPESCRIPT
1// Ta funkcja nigdy nie zwraca wartości. Ona psuje skrypt.2function generateError(message: string, code: number): never {3 throw { message: message, errorCode: code }4}
No dobra, nigdy (hehe) nie powiedziałem, że pokryje wszystkie typy w jednym wpisie. TypeScript oferuje nawet więcej podstawowych i zaawansowanych typów, które mogą ci pomóc w produkowaniu przewidywalnego kodu, który jest łatwy w utrzymaniu. W przyszłości przybliżę także bardziej zaawansowane koncepty, takie jak generyki, interfejsy czy dekoratory. W międzyczasie możesz sprawdzić poniższe linki: