Być może słyszałeś już czym jest asercja typu, ale dla lepszego wprowadzenia poniżej napisałem przykład kodu z asercją.
const uniqueButton = document.querySelector("#unique-button") as HTMLButtonElement
Asercja typu informuje, że otrzymany element drzewa DOM to przycisk. Bez tego TypeScript wiedziałby, że jest to jedynie element HTML.
Dla poniższych przykładów przyjmijmy, że nasz typ User to
type User = {
name: string;
age: number;
}
oraz przykłady obiektów:
const user = {
name: "Pawel",
age: 20,
year: 20,
} as User;
Jest to dynamiczne rzutowanie typu, które może prowadzić do błędów, ale pozwala na nadmiarowe właściwości. Więcej bezpieczeństwa daje statyczne typowanie, czyli tzw. deklaracje typu.
const newUser: User = {
name: "Coder",
age: 20,
year: 2044,
};
Dla powyższego obiektu newUser
TypeScript od razu informuje Object literal may only specify known properties, and year does not exist in type
. Statyczne typowanie sprawdza i oczekuje zgodności wszystkich kluczy danego typu.
Asercje typu są usuwane w czasie kompilacji. Dlatego nie zostanie wygenerowany wyjątek ani null, jeśli asercja typu jest niepoprawna.
Ale kontynuujmy główny wątek - czas na satisfies!
Przykład działania zobaczysz poniżej.
type ApiResponse = {
value: string | null
}
const data2 = {
value: 'success'
} satisfies ApiResponse
data.value.toUpperCase() // SUCCESS
Dla statycznego typowania wynik zakończy się błędem.
const data: ApiResponse = {
value: 'success'
}
data.value.toUpperCase() // 'data.value' is possibly 'null'
Podobny problem pojawi się, gdy kluczami typu jest Unia.
type Keys = "name" | "email" | "height" | "address"
const person1: Record<Keys, string | number> = {
name: "Pawel",
email: "coder@example.com",
height: 180.1,
address: "Poland",
}
person1.name.toUpperCase() // Property 'toUpperCase' does not exist on type 'string | number'
person1.height.toFixed() // Property 'toFixed' does not exist on type 'string | number'
const person2 = {
name: "Pawel",
email: "coder@example.com",
height: 180.1,
address: "Poland",
} satisfies Record<Keys, string | number>
person2.name.toUpperCase() // PAWEL
person2.height.toFixed() // 180
Zauważ, że przy satisfies TypeScript nadal pilnuje czy nie pojawia się błąd niezgodnosci typów.
person2.name.toFixed()) // Property 'toFixed' does not exist on type 'string'
Satisfies jest bardziej elastyczne niż deklaracja typu i bezpieczniejsze niż asercja. Sprawdza, czy obiekt spełnia wszystkie wymagania określonego typu.
Kiedy więc używać asercji typu i satisfies?
Asercja sprawdzi się, gdy chcesz przekazać do TypeScript dodatkowe informacje, których nie posiada o przechowywanym obiekcie, szczególnie podczas pobierania elementów DOM.
Satisfies sprawdzi się w momencie, gdy obiekt ma zachować swój typ, ale potrzebujesz pomocy TypeScript do ostrzegania o popełnionych błędach (jak w przykładzie z unią).
Powrót do artykułów