interface vs type
interface opisuje kształt obiektu i można go rozszerzać oraz łączyć z inną deklaracją o tej samej nazwie, a type to alias dla dowolnego typu, także unii i krotek.
Porównanie w tabeli
#Co opisuje
Rozszerzanie
Dwie deklaracje o tej samej nazwie
Unie i krotki
Implementacja przez klasę (`implements`)
Typowe użycie
Przykład
#interface CourseInterface {
title: string
modules: number
}
type CourseType = {
title: string
modules: number
}
type Difficulty = 'easy' | 'medium' | 'hard'
const html: CourseInterface = { title: 'HTML i CSS', modules: 11 }
const python: CourseType = { title: 'Python', modules: 12 }
const level: Difficulty = 'medium'
console.log(html.title, python.modules, level)HTML i CSS 12 medium
Definicja i zastosowanie
#Obie konstrukcje nadają nazwę kształtowi obiektu i w większości przypadków możesz użyć jednej albo drugiej. Kompilator sprawdza je tak samo: obiekt jest zgodny z typem, jeśli ma wymagane pola o właściwych typach, niezależnie od tego, czy kształt opisano przez interface, czy przez type.
Różnice widać przy rozszerzaniu i przy typach, które nie są obiektami. Interfejs rozszerzasz słowem extends i możesz dopisać do niego pola drugą deklaracją o tej samej nazwie, bo deklaracje się łączą. Alias type rozszerzasz przecięciem &, a dwie deklaracje o tej samej nazwie to błąd kompilacji. Tylko type opisze unię, krotkę czy typ funkcji, bo interface wyraża wyłącznie kształt obiektu.
Do obiektów i kontraktów klas naturalnym wyborem jest interface, zwłaszcza w bibliotekach, gdzie przydaje się łączenie deklaracji. Do unii, krotek, typów funkcji i wyników typów narzędziowych potrzebny jest type. Wiele zespołów ustala prostą zasadę: obiekty przez interface, wszystko inne przez type.
Składnia
#interface Nazwa {
pole: typ
}
type Nazwa = typWięcej przykładów
#interface Config {
darkMode: boolean
}
interface Config {
fontSize: number
}
const config: Config = { darkMode: true, fontSize: 16 }
console.log(Object.keys(config))['darkMode', 'fontSize']
type Profile = { name: string }
type Profile = { age: number }
// Błąd: Duplicate identifier 'Profile'.type Pair = [string, number]
type Status = 'draft' | 'published'
const [title, exp]: Pair = ['Flexbox', 20]
const status: Status = 'draft'
console.log(title, exp, status)Flexbox 20 draft
Dobre praktyki
#- Jeśli potrzebujesz tylko kontraktu bez implementacji, pamiętaj, że klasa abstrakcyjna to inne narzędzie: interfejs nie zawiera kodu, klasa abstrakcyjna może.
- Nazywaj interfejsy od tego, czym obiekt jest (
User,Course), bez przedrostkaI. - Ustal w projekcie jedną konwencję dla zwykłych obiektów, żeby nie zastanawiać się przy każdej deklaracji.
Powiązane hasła
#- interfaceNazwany opis kształtu obiektu, który można rozszerzać i łączyć.
- typeAlias typu: nazwa dla dowolnego typu, także unii, krotek i typów złożonych.
- Unia (A | B)Typ, który może być jednym z kilku typów.
- Przecięcie (A & B)Typ łączący wszystkie pola kilku typów jednocześnie.
- extends (interfejsy)Rozszerzanie interfejsu o nowe pola, na bazie istniejącego.
Widzisz błąd albo brakuje przykładu? Napisz do nas.