Analisi statica

L'analisi statica è un tipo di test che consente di controllare in modo automatico senza eseguirlo o dover scrivere un test automatico. Hai probabilmente già avete già visto questo tipo di test se usate un IDE come VSCode, il controllo eseguito da TypeScript è un tipo di analisi statica e può mostrare sotto forma di linee ondulate sotto errori o avvisi.

ESLint

ESLint è uno strumento che può fornire feedback su possibili problemi del tuo codebase. Questi problemi possono essere di tipo sicuro,ma errori o comportamenti non standard a sé stanti. ESLint consente di applicare una serie di regole da controllare il tuo codebase, inclusi molti dei suoi codici "consigliati" per iniziare.

Un buon esempio di regola ESLint è la sua no-unsafe-finally personalizzata. In questo modo non puoi scrivere istruzioni che modificano flusso di controllo all'interno di un blocco finally. Questa è un'ottima regola, perché farlo è un modo insolito per scrivere codice JavaScript che può essere difficile da seguire. Tuttavia, e qualcosa che un processo di revisione del codice integra dovrebbe essere in grado di rilevare.

  try {
    const result = await complexFetchFromNetwork();
    if (!result.ok) {
      throw new Error("failed to fetch");
    }
  } finally {
    // warning - this will 'overrule' the previous exception!
    return false;
  }

Di conseguenza, ESLint non sostituisce un processo di revisione sano (e uno stile guida che definisce l'aspetto del codebase), perché non per acquisire ogni approccio non ortodosso che uno sviluppatore potrebbe introdurre nel tuo codebase. La guida alle pratiche di ingegneria di Google ha una breve sezione su come semplificare le cose.

ESLint ti consente di infrangere una regola e annotare il codice come "consentito". Ad esempio, può consentire la logica precedente annotandola come segue:

  finally {
    // eslint-disable-next-line no-unsafe-finally
    return false;
  }

Se ti capita di infrangere costantemente una regola, ti consigliamo di disattivarla. Questi ti incoraggiano a scrivere il codice in un determinato modo, ma il tuo team potrebbe essere utilizzato a scrivere il codice in modo diverso ed essere già consapevoli dei rischi che l'importanza di un approccio umile.

Infine, abilitare strumenti di analisi statici su un codebase di grandi dimensioni potrebbe creare di rumore inutile (e impegnativo per il refactoring) del codice che altrimenti funzionava va bene. Quindi è più facile eseguire l'abilitazione nelle prime fasi del ciclo di vita di un progetto.

Plug-in ESLint per il supporto del browser

Puoi aggiungere a ESLint un plug-in che segnali l'uso di API non ampiamente utilizzate supportato o non supportato dal tuo elenco di browser di destinazione. La plug-in-eslint può avvisarti quando un'API potrebbe non essere disponibile per gli utenti, quindi non devi monitorarli costantemente.

Controllo del tipo per l'analisi statica

Durante l'apprendimento di JavaScript, di solito i nuovi sviluppatori vengono introdotti all'idea che si tratta di una lingua digitata male. In altre parole, è possibile dichiarare di un singolo tipo, quindi utilizza la stessa posizione per qualcosa di completamente diverso. È simile a Python e ad altri linguaggi di scripting, ma a differenza linguaggi compilati come C/C++ e Rust.

Questo tipo di linguaggio potrebbe essere adatto per iniziare... che ha reso JavaScript così popolare, ma spesso rappresenta un punto di errore per alcuni codebase o almeno per qualcosa che consenta errori confusi che accadrà. Ad esempio, passando un valore number dove string o un tipo di oggetto previsto, il valore digitato in modo errato può propagarsi prima di causare un errore di TypeError.

TypeScript

TypeScript è la soluzione più diffusa per l'assenza di digitazione di JavaScript informazioni. Questo corso ne fa un uso intensivo. Anche se questo non è un corso TypeScript, può essere una parte importante della tua toolbox poiché fornisce l'analisi statica.

Come breve esempio, questo codice, che prevede di ricevere un callback che accetta un Nome di string e number età:

const callback = (name: string, age: string): void => {
  console.info(name, 'is now', age, 'years old!');
};
onBirthday(callback);

Genera il seguente errore quando viene eseguito tramite TypeScript o anche al passaggio del mouse in un IDE:

bad.ts:4:12 - error TS2345: Argument of type '(name: string, age: string) => void' is not assignable to parameter of type '(name: string, age: number) => void'.
  Types of parameters 'age' and 'age' are incompatible.
    Type 'number' is not assignable to type 'string'.

4 onBirthday(callback);
             ~~~~~~~~

Found 1 error in bad.ts:4
Il codice
  precedente, visualizzato in un IDE con il messaggio di errore visualizzato
  pop-up.
VSCode che indica che è stato trasmesso un codice tipo.

In definitiva, l'obiettivo dell'utilizzo di TypeScript è evitare errori come questo: dovrebbe essere number, non string, per entrare nel tuo progetto. Questo tipo di errore può essere difficile da rilevare con altri tipi di test. Inoltre, il sistema dei tipi può fornire feedback prima ancora di scrivere un test. Questo può semplificare il processo di scrittura del codice fornendoti feedback tempestivi degli errori di digitazione durante lo sviluppo del software, piuttosto che quando il codice alla fine viene eseguito.

La parte più difficile dell'uso di TypeScript è la sua corretta configurazione. Ogni evento il progetto richiede un file tsconfig.json, che viene utilizzato principalmente dallo tsc a riga di comando, viene letto anche dagli IDE come VSCode insieme a molti altri di sviluppo e sviluppo, tra cui Vitest. Questo file contiene centinaia di opzioni e flag. Puoi trovare alcune buone risorse per configurarlo qui:

Suggerimenti generali per TypeScript

Quando configuri e utilizzi TypeScript tramite un file tsconfig.json, mantieni il valore tieni presente quanto segue:

  • Assicurati che i file di origine siano effettivamente inclusi e controllati. Se un file Misteriosamente "non presenta errori", probabilmente perché non viene controllato.
  • Descrivere esplicitamente tipi e interfacce all'interno dei file .d.ts, anziché descriverle implicitamente mentre scrivi le funzioni, può rendere più semplice da testare. È più facile scrivere simulazioni e "fake" versioni di quando le interfacce interessate sono chiare. .

TypeScript implicito qualsiasi

Una delle opzioni di configurazione più potenti e gratificanti di TypeScript è il noImplicitAny flag. Tuttavia, spesso è anche la più difficile da abilitare, soprattutto se hai già un grande codebase. (Il flag noImplicitAny è è attiva per impostazione predefinita se è attiva la modalità strict, ma non altrimenti.

Questo flag farà sì che la funzione restituisca un errore:

export function fibonacci(n) {
  if (n <= 1) {
    return 0;
  } else if (n === 2) {
    return 1;
  }
  return fibonacci(n - 1) + fibonacci(n - 2);
}

Anche se, come lettore, è abbastanza chiaro che n dovrebbe essere un numero, TypeScript non è in grado di confermare con sicurezza questa conferma. Se utilizzi VSCode, passa il mouse sopra la funzione lo descriverà come segue:

function fibonacci(n: any): any

I chiamanti di questa funzione potranno passare attraverso un valore di tipo any (un tipo che consente qualsiasi altro tipo), non solo number. Se attivi il parametro noImplicitAny, puoi salvaguardare questo tipo di codice durante lo sviluppo, senza dover scrivere test approfonditi della logica di business per far passare il codice i tipi di dati sbagliati in luoghi specifici.

La semplice soluzione in questo caso è contrassegnare sia l'argomento n sia il tipo restituito di fibonacci come number.

Il flag noImplicitAny non ti impedisce di scrivere esplicitamente any in il tuo codebase. Puoi comunque scrivere una funzione che accetta o restituisce il tipo any. Garantisce solo che ogni variabile assegni un tipo.