Wyrażenie as const
jest szczególnie użyteczne, gdy chcemy zadeklarować stałe typy w naszym kodzie. W tym artykule
omówimy, czym jest to wyrażenie, jak go używać i jakie korzyści może przynieść.
Czym jest as const
?
as const
to wyrażenie w TypeScript, które pozwala zadeklarować stałe typy. Dzięki niemu można określić, że dana
wartość nie może być zmieniana po jej zadeklarowaniu. W efekcie TypeScript może śledzić te stałe typy i wykrywać
potencjalne błędy w czasie kompilacji.
Użycie as const
z tablicami
Popatrzmy na poniższy przykład:
const numbers = [1, 2, 3] as const
W tym przypadku as const
wskazuje, że tablica numbers
powinna być traktowana jako wartość readonly
. Oznacza to,
że nie możemy jej później zmodyfikować.
// To spowoduje błąd kompilacji
numbers.push(10) // Property 'push' does not exist on type 'readonly [1, 2, 3]'
number[0] = 5 // Cannot assign to '0' because it is a read-only
Użycie as const
z obiektami
Następnym przypadkiem użycia wyrażenia as const
jest deklaracja stałych obiektów.
const person = {
firstName: "John",
lastName: "Doe",
} as const
Wykorzystanie as const
w tym przypadku sprawia, że zarówno obiekt person
jak i jego właściwości firstName
i
fullName
są stałe. To oznacza, że nie możemy zmieniać wartości tych właściwości ani dodawać nowych.
// To spowoduje błąd kompilacji
person.firstName = "Jane" // Cannot assign to 'firstName' because it is a read-only
person.age = 30 // Property 'age' does not exist on type '{ readonly firstName: "John"; readonly lastName: "Doe"; }'
Sprawdźmy do czego jeszcze możemy w praktyce wykorzystać as const
. Weźmy taki obiekt:
const endpoints = {
blog: '/blog',
aboutUs: '/about-us',
contact: '/contact'
}
Teraz chcemy stworzyć funkcję, która jako parametr przyjmie jedną z wartości z powyższego obiektu, jeśli chcemy to mocno typować możemy to zapisać w taki sposób:
const getEndpointData = (endpoint: '/blog' | '/about-us' | '/contact') => { }
Jednak jeśli spróbujemy teraz wywołać tę funkcję podając w parametrze jedną właściwości obiektu endpoints
otrzymamy
błąd:
const data = getEndpointData(endpoints.contact)
// Argument of type 'string' is not assignable to parameter of type '"/blog" | "/about-us" | "contact"'
Dzieję się tak, ponieważ Typescript właściwości tego obiektu traktuje jako jakikolwiek string
, ponieważ w każdym
dowolnym momencie te właściwości mogą zostać nadpisane, dlatego nie muszą one spełniać warunku
'"/blog" | "/about-us" | "contact"'
. Z pomocą przychodzi as const
. Spójrz na cały poprawiony zapis:
const endpoints = {
blog: '/blog',
aboutUs: '/about-us',
contact: '/contact'
} as const
const getEndpointData = (endpoint: '/blog' | '/about-us' | '/contact') => { }
const data = getEndpointData(endpoints.contact)
Taki zapis nie zwróci żadnego błędu. Obiekt endpoints
zadeklarowany jest jako stała i nie można zmieniać jego
właściwości, dlatego spełniony jest typ podany przy parametrze w funkcji getEndpointData
.
Pozostaje jeszcze jeden problem, ponieważ może się wydarzyć, że w deklaracji obiektu chcemy zmienić wartość jakiejś
właściwości. Powiedzmy, że wartość /contact
zmieniła się na /contact-us
. W tym przypadku znowu natkniemy się na
błędy, w końcu typ parametru funkcji getEndpointData
oczekuje wartości contact
, a nie contact-us
. Możemy
zastosować tu trochę magii TypeScript:
const endpoints = {
blog: '/blog',
aboutUs: '/about-us',
contact: '/contact-us'
} as const
type Endpoints = (typeof endpoints)[keyof typeof endpoints]
// to zwróci "/blog" | "/about-us" | "/contact-us"
const getEndpointData = (endpoint: Endpoints) => {
}
const data = getEndpointData(endpoints.contact)
W powyższym kodzie dodaliśmy linię type Endpoints = (typeof endpoints)[keyof typeof endpoints]
, taki zapis powoduje,
że typ Endpoints
zwróci wartości wszystkich właściwości obiektu endpoints
. Dzięki temu przy każdej zmianie czy też
dodaniu nowych wartości w deklaracji obiektu, typ Endpoints
będzie zawierał w sobie aktualne dane.
Podsumowanie
Narzędzie as const
daje nam pewność, że nasze stałe wartości pozostaną stałe i nie zostaną przypadkiem zmienione, co
pomaga w zapobieganiu nieoczekiwanym błędom w czasie wykonywania programu. Dodatkowo, as const
wpływa na optymalizację
kodu, co może przyspieszyć naszą aplikację, oraz zwiększa czytelność kodu, ułatwiając jego zrozumienie dla innych
programistów. Przy właściwym użyciu as const
staje się narzędziem wspomagającym w utrzymaniu wysokiej jakości
kodu, a taże niezawodności naszych aplikacji.