Zespół TypeScript wprowadził nową flagę kompilatora w wersji 6.0 – --noPropertyAccessFromIndexSignature. Po jej włączeniu kompilator odmawia dostępu do właściwości pochodzących z sygnatury indeksu (index signature) za pomocą notacji kropkowej, zmuszając programistów do stosowania notacji nawiasowej i ujawniając potencjalne wartości undefined w czasie kompilacji zamiast w środowisku produkcyjnym.

Dlaczego ta flaga jest ważna

W JavaScript obiekty często pełnią rolę słowników, a TypeScript pozwala na typowanie takich struktur za pomocą sygnatury indeksu, np. Record<string, T>. Język traktuje obj.key oraz obj["key"] jako zamienne, więc kompilator zakłada, że właściwość istnieje, nawet jeśli klucz jest znany dopiero w czasie wykonywania programu (runtime). To ciche założenie jest źródłem wielu awarii: kod, który odwołuje się do obj.missingProp, kompiluje się bez problemów, działa, a następnie wyrzuca błąd, ponieważ wartość jest undefined.

Notacja kropkowa niesie ze sobą dorozumianą gwarancję – informuje czytelników i sprawdzacz typów, że właściwość na pewno istnieje. Notacja nawiasowa, w przeciwieństwie do niej, sygnalizuje niepewność – klucz może nie istnieć, a wynikiem może być undefined. Flaga --noPropertyAccessFromIndexSignature wymusza to rozróżnienie wizualne i semantyczne, zamieniając całą klasę błędów czasu wykonywania na diagnostykę czasu kompilacji.

Jak działa ta flaga

Po włączeniu flagi każde wyrażenie, które uzyskuje dostęp do właściwości za pomocą sygnatury indeksu przy użyciu notacji kropkowej, zostanie oznaczone jako błąd. Kod musi zostać przepisany tak, aby używał nawiasów:

// Before
const name = userData.name;          // OK even if "name" is not in the index

// After enabling the flag
const name = userData["name"];       // Error unless brackets are used

Kompilator stosuje wtedy te same reguły obsługi undefined, których już używa przy dostępie za pomocą nawiasów. Jeśli włączona jest również flaga --noUncheckedIndexedAccess, typ userData["name"] staje się T | undefined, co zmusza programistę do sprawdzenia przypadku braku wartości.

Praktyczne kroki migracji

  1. Włącz flagę w tsconfig.json:

    {
      "compilerOptions": {
        "noPropertyAccessFromIndexSignature": true
      }
    }
    
  2. Uruchom sprawdzacz typów. Wszystkie dostępy do kluczy sygnatury indeksu za pomocą notacji kropkowej pojawią się jako błędy.

  3. Zastąp kropki nawiasami. Zmiana ma charakter mechaniczny i nie wpływa na wydajność czasu wykonywania.

  4. Rozwiąż problem wynikających typów undefined. Dodaj operator nullish coalescing, optional chaining lub jawne sprawdzenia tam, gdzie jest to konieczne.

  5. Rozważ połączenie z --noUncheckedIndexedAccess, aby uzyskać najsilniejszą siatkę bezpieczeństwa. Razem zapewniają one, że każdy dostęp typu słownikowego jest traktowany jako potencjalnie nieobecny.

Kiedy zachować jawne właściwości

Jeśli pole jest częścią stabilnego kontraktu API, zadeklaruj je jako jawną właściwość, zamiast polegać na sygnaturze indeksu. Jawne właściwości nadal pozwalają na stosowanie notacji kropkowej, zachowując gwarancję, że pole zawsze będzie obecne (o ile system typów jest w stanie to zweryfikować). Sygnatury indeksu zarezerwuj dla danych naprawdę dynamicznych, gdzie klucze nie są znane z góry.

Kontrargument: zwiększona ilość kodu (verbosity)

Niektóre zespoły mogą uznać dodatkowe nawiasy za zbędny szum, szczególnie w bazach kodu, które intensywnie korzystają z elastycznych obiektów. Flaga wymusza surowszą dyscyplinę, co w przypadku projektów typu legacy może wymagać znacznej refaktoryzacji. W takich przypadkach flagę można wprowadzać stopniowo, ograniczając ją np. do nowych modułów, podczas gdy reszta bazy kodu będzie adaptować ten wzorzec z czasem.

Na co zwrócić uwagę w przyszłości

Flaga ta jest częścią szerszego dążenia w TypeScript 6.0 do ściślejszego bezpieczeństwa typów. Przyszłe wydania mogą wprowadzić dodatkowe sprawdzenia dotyczące rozprzestrzeniania obiektów (object spread), optional chaining lub wnioskowania typu any. Śledzenie mapy drogowej (roadmap) TypeScript pomoże zespołom zdecydować, kiedy wdrożyć kolejny zestaw funkcji bezpieczeństwa bez zakłócania harmonogramów dostarczania oprogramowania.

Podsumowanie: Włączenie --noPropertyAccessFromIndexSignature sprawia, że rozróżnienie między „ta właściwość jest gwarantowana” a „ta właściwość może nie istnieć” staje się w kodzie jawne, co pozwala wyłapać całą klasę błędów, zanim trafią one na produkcję. Zamiana cichej awarii w czasie wykonywania na błąd w czasie kompilacji to mała zmiana o nieproporcjonalnie dużym wpływie na niezawodność.