Creazione di un semplice strumento di linting
Crei uno strumento diagnostico personalizzato usando la compiler API.
Creazione di un semplice strumento di linting è una lezione TypeScript Academy gratuita su CoddyKit. Questa è la lezione 4 di 4. Puoi leggere la lezione completa qui gratuitamente — poi esercitati direttamente nel browser con un editor di codice integrato e un tutor IA disponibile 24/7. Fa parte del percorso di apprendimento TypeScript Academy, e i tuoi progressi si sincronizzano tra il web e l'app CoddyKit. Il corso TypeScript Academy include 4 lezioni in totale.
Cos'è uno strumento di linting?
Uno strumento di linting analizza il codice sorgente per segnalare problemi di stile o correttezza. Utilizzando l'API del compilatore TypeScript, è possibile creare regole consapevoli dei tipi che i plugin ESLint non possono ottenere da soli.
// Goal: warn when console.log is called in TypeScript filesConfigurazione del progetto
Crei uno script Node.js che carichi un programma TypeScript, attraversi l'AST e segnali le diagnostiche.
import ts from "typescript";
import path from "path";
const files = ["src/index.ts"];
const program = ts.createProgram(files, { strict: true });Definizione di una regola
Una regola è una funzione che riceve un nodo AST e restituisce un messaggio diagnostico facoltativo se la regola viene violata.
type Diagnostic = { file: string; line: number; message: string };
function noConsoleLog(node: ts.Node, sf: ts.SourceFile): Diagnostic | null {
if (!ts.isCallExpression(node)) return null;
const expr = node.expression.getText(sf);
if (expr !== "console.log") return null;
const { line } = sf.getLineAndCharacterOfPosition(node.pos);
return { file: sf.fileName, line: line + 1, message: "No console.log allowed" };
}Attraversamento dell'AST
Scriva una funzione di visita ricorsiva che applichi tutte le regole a ogni nodo di ciascun file sorgente.
function walk(
node: ts.Node,
sf: ts.SourceFile,
rules: ((n: ts.Node, sf: ts.SourceFile) => Diagnostic | null)[]
): Diagnostic[] {
const diags: Diagnostic[] = [];
for (const rule of rules) {
const d = rule(node, sf);
if (d) diags.push(d);
}
ts.forEachChild(node, child => diags.push(...walk(child, sf, rules)));
return diags;
}Esecuzione del linter
Scorra tutti i file sorgente, applichi le regole e stampi le diagnostiche.
const rules = [noConsoleLog];
const allDiagnostics: Diagnostic[] = [];
for (const sf of program.getSourceFiles()) {
if (!sf.isDeclarationFile) {
allDiagnostics.push(...walk(sf, sf, rules));
}
}
allDiagnostics.forEach(d =>
console.log(`${d.file}:${d.line} — ${d.message}`)
);Aggiunta di una regola consapevole dei tipi
Utilizzi il type checker per creare regole che dipendono dal tipo TypeScript di un'espressione.
const checker = program.getTypeChecker();
function noAnyReturn(node: ts.Node, sf: ts.SourceFile): Diagnostic | null {
if (!ts.isFunctionDeclaration(node)) return null;
const sig = checker.getSignatureFromDeclaration(node);
if (!sig) return null;
const ret = checker.getReturnTypeOfSignature(sig);
if (ret.flags & ts.TypeFlags.Any) {
const { line } = sf.getLineAndCharacterOfPosition(node.pos);
return { file: sf.fileName, line: line + 1, message: "Function returns any" };
}
return null;
}Codice di uscita per la CI
Restituisca un codice di uscita diverso da zero quando vengono rilevate diagnostiche, in modo che le pipeline CI possano interrompere la build.
if (allDiagnostics.length > 0) {
console.error(`${allDiagnostics.length} lint error(s)`);
process.exit(1);
}
process.exit(0);Regola: nessuna variabile inutilizzata
L'API del compilatore espone le diagnostiche relative alle variabili inutilizzate tramite ts.getPreEmitDiagnostics, aggiungendo controlli integrati alle regole personalizzate.
const preEmit = ts.getPreEmitDiagnostics(program);
preEmit.forEach(d => {
const msg = ts.flattenDiagnosticMessageText(d.messageText, "
");
console.log(msg);
});Regola: richiedere i tipi restituiti
Una regola che segnala le funzioni prive di annotazioni esplicite del tipo restituito aiuta a imporre una corretta documentazione.
function requireReturnType(node: ts.Node, sf: ts.SourceFile): Diagnostic | null {
if (!ts.isFunctionDeclaration(node)) return null;
if (!node.type) {
const { line } = sf.getLineAndCharacterOfPosition(node.pos);
return { file: sf.fileName, line: line + 1, message: "Missing return type" };
}
return null;
}Confronto con ESLint
Il linter personalizzato completa ESLint. Utilizzi ESLint per le regole di stile e lo strumento basato sull'API del compilatore TypeScript per le regole consapevoli dei tipi che ESLint non è in grado di esprimere.
// ESLint: stylistic and common pattern rules
// Compiler API linter: deep type reasoning, custom constraintsRiepilogo: creazione di un linter
Un linter basato sull'API del compilatore TypeScript crea un programma, attraversa l'AST applicando le regole, interroga facoltativamente il type checker e restituisce un codice diverso da zero in caso di errori. Questo approccio consente di creare regole di linting realmente consapevoli dei tipi.
Verifica rapida
Quale vantaggio offre a un linter basato sull'API del compilatore rispetto a ESLint?
Cosa ha imparato
Ha creato un semplice linter TypeScript utilizzando l'API del compilatore: caricare un programma, attraversare l'AST, applicare le regole (eventualmente consapevoli dei tipi) e segnalare le diagnostiche. Questa è la base per l'analisi statica personalizzata in qualsiasi progetto TypeScript.
Domande Frequenti
La lezione «Creazione di un semplice strumento di linting» è gratuita?
Sì — il testo completo di «Creazione di un semplice strumento di linting» è gratuito qui sul web. Per esercitarvi in modo interattivo (un editor di codice integrato e un tutor IA 24/7) e sbloccare il resto del corso TypeScript Academy, passa a CoddyKit PRO. Il corso TypeScript Academy include 4 lezioni in totale.
Cosa imparerò in «Creazione di un semplice strumento di linting»?
Crei uno strumento diagnostico personalizzato usando la compiler API. Eserciti TypeScript Academy con codice pratico che esegui direttamente nel browser, e un tutor IA 24/7 risponde alle tue domande mentre lavori sulla lezione.
Ho bisogno di esperienza per iniziare TypeScript Academy?
Non è richiesta alcuna esperienza precedente. TypeScript Academy su CoddyKit è strutturato per principianti e studenti avanzati, quindi puoi iniziare da qui o dall'inizio e procedere al tuo ritmo. Questa è la lezione 4 di 4.
Quanto tempo richiede la lezione «Creazione di un semplice strumento di linting»?
La maggior parte delle lezioni CoddyKit richiede circa 5–10 minuti. Ogni lezione è breve e interattiva, quindi fai progressi costanti e riprendi esattamente da dove hai lasciato su web e app.
Posso scrivere ed eseguire codice in questa lezione TypeScript Academy?
Sì. Ogni lezione TypeScript Academy include un editor di codice integrato, quindi scrivi ed esegui codice reale direttamente nel tuo browser e ricevi feedback istantaneo dall'IA — nessuna configurazione locale necessaria.
Tutte le lezioni di questo corso
- Creazione di un programma TypeScript con l'API
- Attraversamento dell'AST con i visitor
- Transformer personalizzati e generazione del codice
- Creazione di un semplice strumento di linting