TypeScript Academy · Lektion

Opbygning af et simpelt linting-værktøj

Opret et brugerdefineret diagnosticeringsværktøj med compiler-API'et

Lektion 4 af 413 trin

Opbygning af et simpelt linting-værktøj er en gratis TypeScript Academy-lektion på CoddyKit. Dette er lektion 4 af 4. Du kan læse hele lektionen gratis nedenfor — og derefter øve dig praktisk i browseren med en indbygget kodeeditor og en AI-vejleder, der er tilgængelig døgnet rundt. Den er en del af læringsforløbet i TypeScript Academy, og dine fremskridt synkroniseres på tværs af nettet og CoddyKit-appen. TypeScript Academy-kurset indeholder 4 lektioner i alt.

Hvad er et lintværktøj?

Et lintværktøj analyserer kildekode for at rapportere problemer med stil eller korrekthed. Ved hjælp af TypeScript-kompilatorens API kan du bygge typebevidste regler, som ESLint-plugins ikke kan opnå alene.

// Goal: warn when console.log is called in TypeScript files

Opsætning af projektet

Opret et Node.js-script, der indlæser et TypeScript-program, gennemgår AST'en og rapporterer diagnostik.

import ts from "typescript";
import path from "path";

const files = ["src/index.ts"];
const program = ts.createProgram(files, { strict: true });

Definer en regel

En regel er en funktion, der modtager en AST-node og returnerer en valgfri diagnostikmeddelelse, hvis reglen overtrædes.

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" };
}

Gennemgå AST'en

Skriv en rekursiv gennemgang, der anvender alle regler på hver node i hver kildefil.

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

Kør lintværktøjet

Gennemgå alle kildefiler, anvend reglerne, og udskriv diagnostikken.

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}`)
);

Tilføj en typebevidst regel

Brug typekontrollen til at bygge regler, der afhænger af TypeScript-typen for et udtryk.

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

Afslutningskode til CI

Returnér en afslutningskode, der ikke er nul, når der findes diagnostik, så CI-processer kan få byggeprocessen til at mislykkes.

if (allDiagnostics.length > 0) {
  console.error(`${allDiagnostics.length} lint error(s)`);
  process.exit(1);
}
process.exit(0);

Regel: Ingen ubrugte variabler

Kompilatorens API stiller diagnostik om ubrugte variabler til rådighed via ts.getPreEmitDiagnostics, så dine brugerdefinerede regler suppleres med indbyggede kontroller.

const preEmit = ts.getPreEmitDiagnostics(program);
preEmit.forEach(d => {
  const msg = ts.flattenDiagnosticMessageText(d.messageText, "
");
  console.log(msg);
});

Regel: Kræv returtyper

En regel, der advarer, når funktioner mangler eksplicitte returtype-annotations, hjælper med at håndhæve disciplin omkring dokumentation.

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

Sammenligning med ESLint

Dit brugerdefinerede lintværktøj supplerer ESLint. Brug ESLint til stilregler og dit værktøj baseret på TypeScript-kompilatorens API til typebevidste regler, som ESLint ikke kan udtrykke.

// ESLint: stylistic and common pattern rules
// Compiler API linter: deep type reasoning, custom constraints

Opsummering: Byg et lintværktøj

Et lintværktøj baseret på TypeScript-kompilatorens API opretter et program, gennemgår AST'en med regler, forespørger eventuelt typekontrollen og afslutter med en kode, der ikke er nul, ved fejl. Denne tilgang gør det muligt at skrive lintregler med fuld typebevidsthed.

Hurtigt tjek

Hvad giver et lintværktøj baseret på kompilatorens API en fordel frem for ESLint?

Det har du lært

Du byggede et enkelt TypeScript-lintværktøj ved hjælp af kompilatorens API: indlæs et program, gennemgå AST'en, anvend regler (eventuelt typebevidste), og rapportér diagnostik. Det er grundlaget for brugerdefineret statisk analyse i ethvert TypeScript-projekt.

Gratis at komme i gang

Lær TypeScript med en AI-underviser — gratis

Skriv og kør rigtig kode i din browser, få øjeblikkelig hjælp fra en AI-underviser døgnet rundt, og fortsæt, hvor du slap, på web eller i appen.

Kurser
101
Lektioner
352

Ofte stillede spørgsmål

Er lektionen “Opbygning af et simpelt linting-værktøj” gratis?

Ja — hele teksten til “Opbygning af et simpelt linting-værktøj” kan læses gratis her på nettet. Hvis du vil øve dig interaktivt med en indbygget kodeeditor og en AI-vejleder døgnet rundt og få adgang til resten af TypeScript Academy-kurset, skal du opgradere til CoddyKit PRO. TypeScript Academy-kurset indeholder 4 lektioner i alt.

Hvad lærer jeg i “Opbygning af et simpelt linting-værktøj”?

Opret et brugerdefineret diagnosticeringsværktøj med compiler-API'et Du øver dig i TypeScript Academy med praktisk kode, som du kører direkte i browseren, og en AI-vejleder døgnet rundt besvarer dine spørgsmål, mens du arbejder dig gennem lektionen.

Skal jeg have erfaring for at begynde på TypeScript Academy?

Der kræves ingen tidligere erfaring. TypeScript Academy på CoddyKit er tilrettelagt for både begyndere og øvede, så du kan starte her eller fra begyndelsen og lære i dit eget tempo. Dette er lektion 4 af 4.

Hvor lang tid tager lektionen “Opbygning af et simpelt linting-værktøj”?

De fleste CoddyKit-lektioner tager cirka 5–10 minutter. Hver lektion er kort og interaktiv, så du gør løbende fremskridt og kan fortsætte, hvor du slap – på både web og app.

Kan jeg skrive og køre kode i denne TypeScript Academy-lektion?

Ja. Alle TypeScript Academy-lektioner har en indbygget kodeeditor, så du kan skrive og køre rigtig kode direkte i din browser og få øjeblikkelig feedback fra AI – uden lokal opsætning.

Alle lektioner i dette kursus

  1. Oprettelse af et TypeScript-program med API'et
  2. Gennemgang af AST'et med visitors
  3. Brugerdefinerede transformere og kodegenerering
  4. Opbygning af et simpelt linting-værktøj
← Tilbage til TypeScript Academy