Historia pytania:
TypeScript jest przeznaczony do dodawania statycznej typizacji do istniejących aplikacji JS. Pojawia się pytanie — jak typizować import, gdy podłączamy zewnętrzny lub własny moduł napisany w czystym JavaScript, gdzie typy nie istnieją? W takim przypadku TypeScript wykorzystuje tak zwane pliki deklaracji (.d.ts) lub automatycznie wyprowadza typy (czasami błędnie).
Problem:
Jeśli przy imporcie TypeScript nie znajdzie odpowiedniego opisu typów, zmienna nabiera typu any, co oznacza — całkowitą utratę bezpieczeństwa typów. Może to prowadzić do błędów, których kompilator nie zauważy i do błędów w czasie wykonywania. Często programiści zapominają jawnie zadeklarować typy dla importowanych funkcji/obiektów.
Rozwiązanie:
Przykład kodu:
// 1. Jawna typizacja importu modułu JS import myFunc from './myLib'; declare function myFunc(x: number): boolean; // 2. Import z modułu JS, dla którego stworzono plik myLib.d.ts z export function myFunc(x: number): boolean; import { myFunc } from './myLib'; // 3. Importujemy moduł bez typizacji i jawnie opisujemy typ import * as legacy from './legacy'; const typedLegacy: { runTask: (name: string) => void } = legacy;
Kluczowe cechy:
Czy TypeScript może automatycznie wyprowadzić typy importowanego modułu JS bez deklaracji?
Nie, jeśli plik jest napisany w JavaScript, bez deklaracji typów TypeScript zmuszony jest założyć any i traci informacje o typach, poza trywialnymi przypadkami (export const x = 1;).
Czy można "rozszerzyć" importowane typy, jeśli pojawiają się nowe pola w module JS?
Tylko jeśli zaktualizujesz plik deklaracji (.d.ts). Jeśli typy są ustalone w .d.ts, TypeScript będzie używać ich jako "prawdy", wszelkie nowe pola pozostaną bez typizacji lub spowodują błąd.
Czy bezpiecznie jest importować zewnętrzny moduł JS do projektu TypeScript, jeśli nie ma dla niego @types/ i deklaracji?
Nie, to znacznie obniża bezpieczeństwo — cała praca z importem okazuje się untyped (any), kompilator nie zgłosi błędów, nawet jeśli moduł jest niedostępny lub API się zmieniło. Praca z takimi modułami jest dozwolona tylko jako tymczasowe rozwiązanie, z jawną typizacją lub izolacją kodu.
Programista importuje zewnętrzną bibliotekę JS bez deklaracji, pewnie korzysta z API, otrzymując typ any. Po aktualizacji biblioteki zmienia się sygnatura metod, ale błędy nie występują, tylko błędy w czasie wykonywania.
Zalety:
Wady:
Tworzony jest plik deklaracji .d.ts lub dodawany jest pakiet @types/, opis API ściśle odpowiada oryginalnemu modułowi JS. Wszystkie importowane metody są typizowane, IDE podpowiada autouzupełnianie, wszelkie niezgodności pokazują błąd kompilacji.
Zalety:
Wady: