En mis primeros años como desarrollador front-end, formaba parte de un equipo de desarrolladores en el que los Tech Leads estaban muy preocupados por "limpiar" el código.

En retrospectiva, entiendo lo que me pedían: que mi código tenía que ser muy descriptivo para que cualquiera pudiera entenderlo. Si alguien revisaba mi código, debía darse cuenta rápida y fácilmente de cómo resolvíamos las historias de usuario del cliente. El resultado final sería un código legible y mantenible.

¿Y cómo podríamos conseguirlo? Bueno, no es tan complicado y los Tech Leads tenían razón, necesitábamos código limpio. Desde entonces he tenido mentores que me han ayudado mucho, y me han ayudado a destapar un deseo de aprendizaje continuo que continúa hasta el día de hoy utilizando ciertos cursos y libros. Y, el concepto de escribir código limpio se me ha quedado grabado.

En este post, me centro en algunos puntos que debemos tener en cuenta a la hora de escribir código limpio, centrándome en TypeScript.


Recuerde, el "mal código" o código espagueti no significa que el código no es utilizable. Pero como programadores, creo que debemos producir software reutilizable, legible y refactorizable.

No añadas contexto innecesario


Si el nombre de tu clase/tipo/objeto te dice algo, no lo repitas en el nombre de tu variable.

Deberías evitarlo:

type Car = {
  carMake: string;
  carModel: string;
  carColor: string;
}

function print(car: Car): void {
  console.log(`${car.carMake} ${car.carModel} (${car.carColor})`);
}

Haz esto en su lugar:

 type Car = {
  make: string;
  model: string;
  color: string;
}

function print(car: Car): void {
  console.log(`${car.make} ${car.model} (${car.color})`);
}

Utilizar enum


Los enums pueden ayudarte a documentar la intención del código. Por ejemplo cuando nos preocupa que los valores sean diferentes en lugar del valor exacto de los mismos.

Debe evitarse:

const GENRE = {
  ROMANTIC: 'romantic',
  DRAMA: 'drama',
  COMEDY: 'comedy',
  DOCUMENTARY: 'documentary',
}

projector.configureFilm(GENRE.COMEDY);

class Projector {
  // declaration of Projector
  configureFilm(genre) {
    switch (genre) {
      case GENRE.ROMANTIC:
        // some logic to be executed 
    }
  }
}

Haz esto en su lugar:

enum GENRE {
  ROMANTIC,
  DRAMA,
  COMEDY,
  DOCUMENTARY,
}

projector.configureFilm(GENRE.COMEDY);

class Projector {
  // declaration of Projector
  configureFilm(genre) {
    switch (genre) {
      case GENRE.ROMANTIC:
        // some logic to be executed 
    }
  }

Los nombres de las funciones deben decir lo que hacen


Deben evitarse:

function addToDate(date: Date, month: number): Date {
  // ...
}

const date = new Date();

// It's hard to tell from the function name what is added
addToDate(date, 1);

Podrías hacer esto

function addMonthToDate(date: Date, month: number): Date {
  // ...
}

const date = new Date();
addMonthToDate(date, 1);

Preferir la programación funcional a la imperativa


Debería evitar:

const contributions = [
  {
    name: 'Uncle Bobby',
    linesOfCode: 500
  }, {
    name: 'Suzie Q',
    linesOfCode: 1500
  }, {
    name: 'Jimmy Gosling',
    linesOfCode: 150
  }, {
    name: 'Gracie Hopper',
    linesOfCode: 1000
  }
];

let totalOutput = 0;

for (let i = 0; i < contributions.length; i++) {
  totalOutput += contributions[i].linesOfCode;
}

Una mejor práctica podría ser

const contributions = [
  {
    name: 'Uncle Bobby',
    linesOfCode: 500
  }, {
    name: 'Suzie Q',
    linesOfCode: 1500
  }, {
    name: 'Jimmy Gosling',
    linesOfCode: 150
  }, {
    name: 'Gracie Hopper',
    linesOfCode: 1000
  }
];

const totalOutput = contributions
  .reduce((totalLines, output) => totalLines + output.linesOfCode, 0);

Evitar los condicionales negativos


Se deben evitar:

function isEmailNotUsed(email: string): boolean {
  // ...
}

if (isEmailNotUsed(email)) {
  // ...
}

Se podría sustituir por

function isEmailUsed(email: string): boolean {
  // ...
}

if (!isEmailUsed(email)) {
  // ...
}

Prefiero la inmutabilidad


Debería evitar:

interface Config {
  host: string;
  port: string;
  db: string;
}

Se puede modificar a

interface Config {
  readonly host: string;
  readonly port: string;
  readonly db: string;
}

tipo vs. interfaz (Type vs Interfaces)


Utilices un tipo cuando necesite una unión o intersección. Utiliza una interfaz cuando quieras extends o implements. No hay una regla estricta, sin embargo, utiliza la que más te convenga.

Debe evitarse:

interface EmailConfig {
  // ...
}

interface DbConfig {
  // ...
}

interface Config {
  // ...
}

//...

type Shape = {
  // ...
}

Haz esto en su lugar:

type EmailConfig = {
  // ...
}

type DbConfig = {
  // ...
}

type Config  = EmailConfig | DbConfig;

// ...

interface Shape {
  // ...
}

class Circle implements Shape {
  // ...
}

class Square implements Shape {
  // ...
}

Un único concepto por prueba


Las pruebas también deben seguir el principio de responsabilidad única. Hacer una sola afirmación por prueba unitaria.

Debe evitarse:

import { assert } from 'chai';

describe('AwesomeDate', () => {
  it('handles date boundaries', () => {
    let date: AwesomeDate;

    date = new AwesomeDate('1/1/2015');
    assert.equal('1/31/2015', date.addDays(30));

    date = new AwesomeDate('2/1/2016');
    assert.equal('2/29/2016', date.addDays(28));

    date = new AwesomeDate('2/1/2015');
    assert.equal('3/1/2015', date.addDays(28));
  });
});

Una mejor práctica podría ser

import { assert } from 'chai';

describe('AwesomeDate', () => {
  it('handles 30-day months', () => {
    const date = new AwesomeDate('1/1/2015');
    assert.equal('1/31/2015', date.addDays(30));
  });

  it('handles leap year', () => {
    const date = new AwesomeDate('2/1/2016');
    assert.equal('2/29/2016', date.addDays(28));
  });

  it('handles non-leap year', () => {
    const date = new AwesomeDate('2/1/2015');
    assert.equal('3/1/2015', date.addDays(28));
  });
});

Conclusión


Hay toneladas de cosas que decir sobre el código limpio, un artículo no es suficiente, sin embargo; es de suma importancia ir cada día mejorando.

Fuente

Plataforma de cursos gratis sobre programación