W TypeScripcie mamy do dyspozycji dwa podobne byty, które przy deklarowaniu typów wydają się być zamienne - type oraz interface. Czy te dwa typy czymś się różnią?
type Person1 = {
name: string
}
interface Person2 {
name: string
}W ogólności, poza subtelną różnicą w składni - do type “przypisujemy” deklarację, a interface deklarujemy wprost, bez znaku = - te dwie konstrukcje można stosować zamiennie. Obie będą weryfikować typ, np.:
const alice: Person1 = {
name: "Alice",
age: 20,
// -> tu będzie błąd
}
const bob: Person1 = {
name: "Bob",
age: 25,
// -> tu będzie błąd
}Obie konstrukcje możemy też używać zamiennie w bardziej złożonych przykładach, jak sygnatury indeksu czy typy funkcji, np.:
type Dictionary1 = { [key: string]: string }
interface Dictionary2 {
[key: string]: string
}Zarówno typ, jak i interfejs możemy “podziedziczyć” (właściwe określenie w świecie TS to raczej - rozszerzyć):
class Employee1 implements Person1 {
name: string
}
class Employee2 implements Person2 {
name: string
}Jakie zatem mamy różnice?
- Jeśli definiujemy unię, to możemy zastosować tylko tylko
type:type State = 'on' | 'off' - Tylko
typemoże rozszerzać unię:type StateExtended = State & 'paused' - Teoretycznie interfejsem można wyrazić krotkę, ale za pomocą typu jest to dużo bardziej czytelne i naturalne:
type Pair = [number, number]
// zamiast jakiegoś dziwadła
interface Tuple {
0: number
1: number
length: 2
}- Z drugiej strony
interfaceumożliwia scalanie deklaracji, czyli coś w stylupartial classz C#. Chodzi o to, że możemy w jednym pliku zadeklarować interfejs, a w innym - “dalszą jego część”, finalnie uzyskując interfejs, który będzie połączeniem obydwu deklaracji, np.:
// plik Person.ts
interface Person {
name: string
}
// plik PersonAddress.ts
interface Person {
address: string
}Ten myk nie jest potrzebny raczej w naszym kodzie (możemy przecież scalić deklaracje do jednego pliku), ale przydaje się, gdy chcemy zmodyfikować typ, który dostajemy z jakiejś zewnętrznej biblioteki. Ten mechanizm wykorzystuje też podstawowa biblioteka TS - nowości i zmiany w kolejnych standardach ES to kolejne pliki, które rozszerzają wcześniejsze deklaracje: zatem wybierając odpowiedni standard ES, de facto wybieramy zestaw plików z deklaracjami, które są scalane.
Ten wpis jest częścią serii o TypeScripcie, inspirowaną lekturą książki D. Vanderkama pt. “TypeScript. Skuteczne programowanie”.