Usamos cookies para mejorar tu experiencia en el sitio
CodeWorlds

Konfiguracja TypeScript i narzędzia

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.

tsconfig.json — centrum dowodzenia

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}

Kluczowe opcje kompilatora

Target — wersja JavaScript na wyjściu:

  • ES5
    — kompatybilność ze starszymi przeglądarkami
  • ES2020
    — nowoczesne środowiska (nullish coalescing, optional chaining)
  • ESNext
    — najnowsze funkcje

Module — system modułów:

  • CommonJS
    — Node.js (
    require
    /
    module.exports
    )
  • ESNext
    — moduły ES (
    import
    /
    export
    )
  • NodeNext
    — Node.js z obsługą ESM

Lib — jakie API są dostępne:

  • DOM
    — API przeglądarki (document, window)
  • ES2020
    — metody jak
    Promise.allSettled
    ,
    BigInt
  • WebWorker
    — API Web Workers

Strict Mode — maksymalne bezpieczeństwo

Flaga

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}

Path Aliases — skróty nawigacyjne

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';

Declaration Files (.d.ts)

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:

  1. Automatyczne — TypeScript generuje je z flagą
    declaration: true
  2. Ręczne — piszesz sam dla kodu JS bez typów
  3. DefinitelyTyped — społecznościowe typy dla popularnych bibliotek

DefinitelyTyped (@types/*)

Wiele 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/jest

TypeScript 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}

ESLint z TypeScript

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
    any
  • no-unused-vars
    — wykrywa nieużywane zmienne (z obsługą TypeScript)
  • prefer-nullish-coalescing
    — preferuj
    ??
    zamiast
    ||
  • prefer-optional-chain
    — preferuj
    a?.b
    zamiast
    a && a.b
  • strict-boolean-expressions
    — zabrania niejawnych konwersji boolean

Opcje jakości kodu

Dodatkowe 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}
Ir a CodeWorlds