Clean Code für TypeScript - Teil 1

Nachdem ich über das Material nach den Prinzipien von Clean Code für TypeScript gestolpert war und es gelesen hatte, beschloss ich, seine Übersetzung aufzunehmen. Hier möchte ich einige Auszüge aus dieser Übersetzung mit Ihnen teilen, da einige Punkte des reinen TypeScript-Codes dieselben Prinzipien für JavaScript wiederholen. Ich werde sie hier nicht beschreiben. Wenn es interessant sein wird, wurde die Übersetzung für JS bereits auf dem Hub (@ BoryaMogila ) oder veröffentlicht Sie können sich mit ihnen in der Originalquelle vertraut machen.



Lassen Sie uns zunächst herausfinden, was diese Prinzipien von sauberem Code sind. Leider ist es unwahrscheinlich, dass es eine klare Definition von sauberem Code gibt. Zum Teil hängt alles von den Menschen ab, zum Beispiel, wenn Sie ins Museum kommen, schauen Sie sich das Bild an und denken, was Hässlichkeit ist, aber dann kommt eine andere Person und sagt, was für eine Pracht. Ja, wir haben einige bestimmte, allgemeine Merkmale der Welt, in denen wir sagen können, dass das eine oder andere schön ist, aber wir werden sicherlich nicht in der Lage sein, all dies zu definieren. Hier sind es also nur einige kleine Kriterien dieser Schönheit, deren Einhaltung er sich seitdem aussucht. Dies sind nicht die Regeln, die in Granit geschnitzt sind. Dies sind nur Empfehlungen.


Variablen


Verwenden Sie enum zum Dokumentieren


Enams kann Ihnen helfen, Ihren Code zu dokumentieren. Wenn wir zum Beispiel befürchten, dass sich unsere Variablen von den Werten unterscheiden.


Schlecht:


const GENRE = { ROMANTIC: 'romantic', DRAMA: 'drama', COMEDY: 'comedy', DOCUMENTARY: 'documentary', } projector.configureFilm(GENRE.COMEDY); class Projector { // delactation of Projector configureFilm(genre) { switch (genre) { case GENRE.ROMANTIC: // some logic to be executed } } } 

Gut


 enum GENRE { ROMANTIC, DRAMA, COMEDY, DOCUMENTARY, } projector.configureFilm(GENRE.COMEDY); class Projector { // delactation of Projector configureFilm(genre) { switch (genre) { case GENRE.ROMANTIC: // some logic to be executed } } } 

Funktionen


Vermeiden Sie die Typprüfung


TypeScript ist eine Obermenge der JavaScript-Syntax und fügt zusätzliche statische Typprüfungen für die Sprache hinzu. Geben Sie lieber Variablentypen, Parameter und Rückgabewerte an, um TypeScript optimal nutzen zu können. Dies erleichtert das zukünftige Refactoring.


Schlecht:


 function travelToTexas(vehicle: Bicycle | Car) { if (vehicle instanceof Bicycle) { vehicle.pedal(currentLocation, new Location('texas')); } else if (vehicle instanceof Car) { vehicle.drive(currentLocation, new Location('texas')); } } 

Gut


 type Vehicle = Bicycle | Car; function travelToTexas(vehicle: Vehicle) { vehicle.move(currentLocation, new Location('texas')); } 

Verwenden Sie Iteratoren und Generatoren


Verwenden Sie Generatoren und Iteratoren, wenn Sie mit Datensammlungen arbeiten, die als Stream verwendet werden.
Dafür gibt es mehrere Gründe:


  • trennt das aufgerufene Objekt von der Generatorimplementierung in dem Sinne, dass das aufgerufene Objekt entscheidet, wie viele Elemente
    Zugang haben
  • Lazy Execution, Artikel werden auf Anfrage weitergegeben
  • Eingebaute Unterstützung für die Iteration von Elementen mithilfe der for-of Syntax
  • Mit Iteratoren können Sie optimierte Iteratormuster implementieren

Schlecht:


 function fibonacci(n: number): number[] { if (n === 1) return [0]; if (n === 2) return [0, 1]; const items: number[] = [0, 1]; while (items.length < n) { items.push(items[items.length - 2] + items[items.length - 1]); } return items; } function print(n: number) { fibonacci(n).forEach(fib => console.log(fib)); } // Print first 10 Fibonacci numbers. print(10); 

Gut


 // Generates an infinite stream of Fibonacci numbers. // The generator doesn't keep the array of all numbers. function* fibonacci(): IterableIterator<number> { let [a, b] = [0, 1]; while (true) { yield a; [a, b] = [b, a + b]; } } function print(n: number) { let i = 0; for (const fib of fibonacci()) { if (i++ === n) break; console.log(fib); } } // Print first 10 Fibonacci numbers. print(10); 

Es gibt Bibliotheken, mit denen Sie mit Iteratoren wie mit Ihren eigenen Arrays arbeiten können, indem Sie Methoden wie map , slice , forEach usw. verketten. Im Beispiel itiriri finden Sie Informationen zur erweiterten Manipulation von Iteratoren (oder itiriri-async zur Manipulation von asynchronen Iteratoren).


 import itiriri from 'itiriri'; function* fibonacci(): IterableIterator<number> { let [a, b] = [0, 1]; while (true) { yield a; [a, b] = [b, a + b]; } } itiriri(fibonacci()) .take(10) .forEach(fib => console.log(fib)); 

Objekte und Datenstrukturen


Verwenden Sie Getter und Setter


TypeScript unterstützt die Syntax von Gettern und Setzern. Die Verwendung von Gettern und Setzern für den Zugriff auf Objektdaten ist viel besser als der direkte Zugriff auf deren Eigenschaften. "Warum?" du fragst Hier ist eine Liste von Gründen:


  • Wenn Sie mehr als nur den Zugriff auf eine Eigenschaft implementieren möchten, müssen Sie die Implementierung an einem Ort und nicht im gesamten Code ändern
  • Die Validierung ist auf der set Implementierungsebene einfach zu implementieren
  • Kapselung des internen Zustands
  • Einfaches Hinzufügen von Protokollierung und Fehlerbehandlung auf Getter- und Setter-Ebene
  • Sie können Eigenschaften Ihres Objekts beispielsweise träge vom Server laden

Schlecht:


 type BankAccount = { balance: number; // ... } const value = 100; const account: BankAccount = { balance: 0, // ... }; if (value < 0) { throw new Error('Cannot set negative balance.'); } account.balance = value; 

Gut


 class BankAccount { private accountBalance: number = 0; get balance(): number { return this.accountBalance; } set balance(value: number) { if (value < 0) { throw new Error('Cannot set negative balance.'); } this.accountBalance = value; } // ... } //  `BankAccount`   . //    ,      , //      ``, //      . const account = new BankAccount(); account.balance = 100; 

Erstellen Sie Objekte mit privaten / sicheren Feldern


TypeScript unterstützt public (Standard) , protected und private Methoden für den Zugriff auf Klasseneigenschaften.


Schlecht:


 class Circle { radius: number; constructor(radius: number) { this.radius = radius; } perimeter() { return 2 * Math.PI * this.radius; } surface() { return Math.PI * this.radius * this.radius; } } 

Gut


 class Circle { constructor(private readonly radius: number) { } perimeter() { return 2 * Math.PI * this.radius; } surface() { return Math.PI * this.radius * this.radius; } } 

Sehr geehrte Leser, nach welchen Grundsätzen arbeiten Sie mit TypeScript?


Fortsetzung folgt...

Source: https://habr.com/ru/post/de484402/


All Articles