Código limpio para TypeScript - Parte 1

Después de tropezar con el material de acuerdo con los principios de código limpio para TypeScript y leerlo, decidí retomar su traducción. Aquí quiero compartir con ustedes algunos extractos de esta traducción, ya que algunos puntos de código TypeScript puro repiten los mismos principios para JavaScript, no los describiré aquí, si será interesante, la traducción para JS ya se publicó en el hub (@ BoryaMogila ) o Puede familiarizarse con ellos en la fuente original .



Para comenzar, descubramos cuáles son estos principios de código limpio. Pero desafortunadamente es poco probable que dé una definición clara de código limpio. En parte, todo depende de las personas, por ejemplo, cuando vienes al museo miras la imagen y piensas qué es la fealdad, pero luego aparece otra persona y dice qué esplendor. Sí, tenemos ciertas características definidas y generales del mundo donde podemos decir que una u otra es hermosa, pero ciertamente no podemos dar una definición a todo esto. Entonces, aquí hay solo algunos pequeños criterios de esta belleza, cuya observancia se elige a sí mismo desde entonces. Estas no son las reglas que están talladas en granito. Estas son solo recomendaciones.


Variables


Use enum para documentar


Enam's puede ayudarlo a documentar su código. Por ejemplo, cuando nos preocupa que nuestras variables sean diferentes de los valores.


Malo:


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

Bueno


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

Las funciones


Evite la verificación de tipos


TypeScript es un superconjunto de sintaxis de JavaScript y agrega comprobaciones de tipo estático adicionales para el idioma. Siempre prefiera especificar tipos de variables, parámetros y valores de retorno para aprovechar al máximo TypeScript. Esto facilita la refactorización futura.


Malo:


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

Bueno


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

Usa iteradores y generadores


Use generadores e iteradores cuando trabaje con colecciones de datos que se usan como una secuencia.
Hay varias razones para esto:


  • separa el objeto llamado de la implementación del generador en el sentido de que el objeto llamado decide cuántos elementos
    tener para acceder
  • ejecución perezosa, los artículos se pasan a pedido
  • soporte incorporado para iterar elementos usando sintaxis for-of
  • los iteradores le permiten implementar patrones de iterador optimizados

Malo:


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

Bueno


 // 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); 

Existen bibliotecas que le permiten trabajar con iteradores de la misma manera que con sus propias matrices, encadenando métodos como map , slice , forEach , etc. Consulte el ejemplo de itiriri para la manipulación avanzada de iteradores (o itiriri-async para manipular iteradores asincrónicos).


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

Objetos y estructuras de datos


Usa captadores y colocadores


TypeScript admite la sintaxis de getters y setters. Usar getters y setters para acceder a datos de objetos es mucho mejor que acceder directamente a sus propiedades. "¿Por qué?" usted pregunta Aquí hay una lista de razones:


  • Si desea implementar más que solo el acceso a una propiedad, debe cambiar la implementación en un solo lugar, y no en todo el código
  • La validación es fácil de implementar en el nivel de implementación set
  • Encapsulación del estado interno
  • Fácil de agregar registro y manejo de errores a nivel de captador y definidor
  • Puede cargar perezosamente las propiedades de su objeto, por ejemplo, desde el servidor

Malo:


 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; 

Bueno


 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; 

Crear objetos con campos privados / seguros


TypeScript admite medios public (predeterminados) , protected y private para acceder a las propiedades de la clase.


Malo:


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

Bueno


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

Estimados lectores, ¿qué principios utilizan al usar TypeScript?


Continuará ...

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


All Articles