programowanieFrontend developer

Jak działa mechanizm rozszerzalnych typów (index signatures) w TypeScript? Do czego służy, jakie ma niuanse i jakie ryzyka wiążą się z projektowaniem takich struktur?

Zdaj rozmowy kwalifikacyjne z asystentem AI Hintsage

Odpowiedź.

Historia pytania

TypeScript umożliwia opisanie obiektów z dynamicznymi nazwami właściwości, gdy niemożliwe jest wcześniejsze określenie wszystkich kluczy. Używane są do tego index signatures, które pojawiły się jako sposób typizacji obiektów-warianci (map, dane z zewnętrznego serwera itd.).

Problem

Bez index signature obiekt jest postrzegany wyłącznie według wcześniej określonych kluczy, wszelkie inne będą generować błąd kompilacji. Przy tym niepoprawne zadeklarowanie sygnatury może rozmyć typy wszystkich właściwości obiektu, zmniejszyć surowość typów i prowadzić do błędów.

Rozwiązanie

Jawnie deklaruj index signature tylko tam, gdzie jest to uzasadnione. Do typizacji tablic obiektów na podstawie klucza stringowego używaj następującej formy:

Przykład kodu:

interface Dictionary { [key: string]: number; length?: number; } const sample: Dictionary = { apples: 4, oranges: 10 }; sample['bananas'] = 6;

Kluczowe cechy:

  • Umożliwia opisywanie kolekcji z dowolnymi kluczami
  • Opiera się na jednolitym typie wartości wszystkich elementów
  • Z powodu sygnatury wszystkie dodatkowe właściwości muszą odpowiadać temu typowi

Pytania z przymrużeniem oka.

Czy można przypisać różne typy wartości do różnych kluczy w index signature?

Nie, typ rozciąga się na cały zestaw kluczy, jeśli wskaźnikujesz [key: string]: number, to i sample.length musi być number: często wywołuje to błąd przy wspólnym użyciu index signature i znanych właściwości.

Czy można używać index signature z symbolami (symbol)?

Tak, od ES6 TypeScript obsługuje index signature na podstawie symbolu:

interface SymbolMap { [key: symbol]: string; }

Co się stanie, jeśli zadeklarujesz obiekt z index signature i dodatkowymi właściwościami innego typu?

Kompilator zgłosi błąd, jeśli typ właściwości nie jest zgodny z zadeklarowanym typem wartości index signature. Można to obejść, używając typu unii lub wydzielając takie pola do oddzielnego interfejsu.

Typowe błędy i antywzorce

  • Nadmierne użycie index signature zamiast ścisłych interfejsów
  • Rozmycie typu obiektów
  • Nieprawidłowe łączenie znanych i indeksowych właściwości

Przykład z życia

Negatywny przypadek

Dla każdej odpowiedzi z serwera używano interfejsu {[key: string]: any}, co prowadziło do wnikających błędów z powodu utraty kontroli nad strukturą danych.

Zalety:

  • Uniwersalność

Wady:

  • Całkowita utrata surowej typizacji wewnątrz obiektu
  • Ukryte błędy, „niespodzianki” na produkcji

Pozytywny przypadek

Użycie index signature wyłącznie dla słowników (np. konfiguracja według klucza), a wtedy jawnie znane właściwości — tylko z deklaracją ich typu poza sygnaturą.

Zalety:

  • Jasna struktura dla kolekcji/map
  • Zachowana surowa typizacja dla znanych pól

Wady:

  • Wymaga więcej czasu na zaprojektowanie odpowiedniej architektury obiektów