W Parku Jurajskim nawet najlepszy system genetyczny jest bezużyteczny bez właściwej kalibracji sprzętu laboratoryjnego. Tak samo TypeScript bez odpowiedniej konfiguracji nie wykorzysta swojego pełnego potencjału. Plik
tsconfig.json to Twój panel sterowania — definiuje, jak kompilator TypeScript interpretuje i transformuje Twój kod.Każdy projekt TypeScript zaczyna się od pliku
tsconfig.json w katalogu głównym. To plik JSON definiujący opcje kompilatora, które pliki mają być kompilowane i jak ma wyglądać wynik:1{
2 "compilerOptions": {
3 "target": "ES2020",
4 "module": "ESNext",
5 "lib": ["ES2020", "DOM", "DOM.Iterable"],
6 "outDir": "./dist",
7 "rootDir": "./src",
8 "strict": true,
9 "esModuleInterop": true,
10 "skipLibCheck": true,
11 "forceConsistentCasingInFileNames": true
12 },
13 "include": ["src/**/*"],
14 "exclude": ["node_modules", "dist"]
15}Target — wersja JavaScript na wyjściu:
ES5 — kompatybilność ze starszymi przeglądarkamiES2020 — nowoczesne środowiska (nullish coalescing, optional chaining)ESNext — najnowsze funkcjeModule — system modułów:
CommonJS — Node.js (require/module.exports)ESNext — moduły ES (import/export)NodeNext — Node.js z obsługą ESMLib — jakie API są dostępne:
DOM — API przeglądarki (document, window)ES2020 — metody jak Promise.allSettled, BigIntWebWorker — API Web WorkersFlaga
strict: true włącza wszystkie rygorystyczne sprawdzenia jednocześnie. To jak włączenie pełnych zabezpieczeń w Parku Jurajskim — żaden dinozaur nie wymknie się z zagrody:1// strict: true włącza WSZYSTKIE poniższe:
2{
3 "strictNullChecks": true, // null/undefined muszą być obsłużone
4 "strictFunctionTypes": true, // ścisłe typowanie parametrów funkcji
5 "strictBindCallApply": true, // ścisłe typowanie bind/call/apply
6 "strictPropertyInitialization": true, // właściwości muszą być zainicjalizowane
7 "noImplicitAny": true, // zakaz niejawnego any
8 "noImplicitThis": true, // this musi mieć typ
9 "alwaysStrict": true, // "use strict" w każdym pliku
10 "useUnknownInCatchVariables": true // catch(e) to unknown, nie any
11}Przykład różnicy z
strictNullChecks:1// BEZ strictNullChecks — błąd w runtime!
2function getDinoName(id: string): string {
3 const dino = dinosaurs.find(d => d.id === id);
4 return dino.name; // Runtime error: Cannot read property 'name' of undefined
5}
6
7// Z strictNullChecks — TypeScript wymusza obsługę null
8function getDinoName(id: string): string | undefined {
9 const dino = dinosaurs.find(d => d.id === id);
10 return dino?.name; // Bezpieczne — zwraca undefined jeśli nie znaleziono
11}W dużych projektach importy mogą stać się nieczytelne. Path aliases pozwalają tworzyć skróty:
1{
2 "compilerOptions": {
3 "baseUrl": ".",
4 "paths": {
5 "@models/*": ["src/models/*"],
6 "@utils/*": ["src/utils/*"],
7 "@services/*": ["src/services/*"],
8 "@config": ["src/config/index.ts"]
9 }
10 }
11}Zamiast:
1import { Dinosaur } from '../../../models/dinosaur';
2import { formatDate } from '../../utils/helpers';Piszesz:
1import { Dinosaur } from '@models/dinosaur';
2import { formatDate } from '@utils/helpers';Pliki deklaracji opisują typy dla kodu JavaScript. Mają rozszerzenie
.d.ts i nie zawierają implementacji — tylko sygnatury typów:1// dinosaur.d.ts — deklaracja typów
2declare interface IDinosaur {
3 id: string;
4 name: string;
5 species: string;
6 dangerLevel: 1 | 2 | 3 | 4 | 5;
7}
8
9declare function findDinosaur(id: string): IDinosaur | null;
10declare const PARK_NAME: string;
11
12// Deklaracja modułu dla biblioteki JS bez typów
13declare module 'dino-tracker' {
14 export function trackPosition(id: string): [number, number];
15 export function getStatus(id: string): 'active' | 'sleeping' | 'escaped';
16}Trzy rodzaje plików deklaracji:
declaration: trueWiele bibliotek JavaScript nie ma wbudowanych typów. Repozytorium DefinitelyTyped zawiera typy tworzone przez społeczność:
1# Instalacja typów dla popularnych bibliotek
2npm install --save-dev @types/node
3npm install --save-dev @types/express
4npm install --save-dev @types/lodash
5npm install --save-dev @types/jestTypeScript automatycznie rozpoznaje pakiety
@types/* — nie musisz ich importować. Jeśli biblioteka ma wbudowane typy (jak axios czy date-fns), nie potrzebujesz osobnego pakietu @types.Opcja
typeRoots w tsconfig kontroluje, skąd TypeScript ładuje typy:1{
2 "compilerOptions": {
3 "typeRoots": ["./node_modules/@types", "./src/types"]
4 }
5}TypeScript ma własne sprawdzenia typów, ale ESLint z pluginem
@typescript-eslint dodaje reguły stylistyczne i zaawansowane analizy:1{
2 "parser": "@typescript-eslint/parser",
3 "plugins": ["@typescript-eslint"],
4 "extends": [
5 "eslint:recommended",
6 "plugin:@typescript-eslint/recommended",
7 "plugin:@typescript-eslint/recommended-requiring-type-checking"
8 ],
9 "parserOptions": {
10 "project": "./tsconfig.json"
11 },
12 "rules": {
13 "@typescript-eslint/no-explicit-any": "warn",
14 "@typescript-eslint/no-unused-vars": ["error", { "argsIgnorePattern": "^_" }],
15 "@typescript-eslint/prefer-nullish-coalescing": "error",
16 "@typescript-eslint/prefer-optional-chain": "error"
17 }
18}Najważniejsze reguły
@typescript-eslint:no-explicit-any — ostrzega przed użyciem anyno-unused-vars — wykrywa nieużywane zmienne (z obsługą TypeScript)prefer-nullish-coalescing — preferuj ?? zamiast ||prefer-optional-chain — preferuj a?.b zamiast a && a.bstrict-boolean-expressions — zabrania niejawnych konwersji booleanDodatkowe flagi kompilatora pomagające utrzymać jakość kodu:
1{
2 "compilerOptions": {
3 "noUnusedLocals": true, // błąd przy nieużywanych zmiennych
4 "noUnusedParameters": true, // błąd przy nieużywanych parametrach
5 "noImplicitReturns": true, // każda ścieżka musi zwracać wartość
6 "noFallthroughCasesInSwitch": true, // wymusza break w switch
7 "noUncheckedIndexedAccess": true, // arr[i] to T | undefined
8 "exactOptionalPropertyTypes": true // undefined !== pominięcie pola
9 }
10}Opcja
noUncheckedIndexedAccess jest szczególnie przydatna — zabezpiecza przed błędami indeksowania:1const dinos = ["T-Rex", "Raptor", "Triceratops"];
2
3// BEZ noUncheckedIndexedAccess
4const first: string = dinos[0]; // OK, ale dinos[100] też byłoby "string"!
5
6// Z noUncheckedIndexedAccess
7const first: string | undefined = dinos[0]; // TypeScript wymusza sprawdzenie
8if (first) {
9 console.log(first.toUpperCase()); // Bezpieczne
10}