5 conceitos de código limpo em TypeScript

Mar 30 2023
Como Escrever Código Super Legível
A última vez que escrevi um artigo 7 Bad Code Smells In Typescript, o artigo recebeu muita atenção e elogios. Portanto, acho que muitas pessoas querem saber mais sobre isso e decidi escrever outro artigo sobre isso.
Foto de Daniel K Cheung no Unsplash

A última vez que escrevi um artigo 7 Bad Code Smells In Typescript, o artigo recebeu muita atenção e elogios. Portanto, acho que muitas pessoas querem saber mais sobre isso e decidi escrever outro artigo sobre isso.

Neste artigo, não vou repetir os maus cheiros de código anteriores. Hoje vamos discutir outros 5 conceitos de código limpo em Typescript.

1. As funções devem fazer uma coisa

Se as funções fazem mais de uma coisa, elas são mais difíceis de mudar, testar e refatorar.

Prática ruim:

function updateDeprecatedDependencies(dependicies: Dependency[]) {
  dependicies.forEach((dependency) => {
    const dependencyVersion = getDependencyVersion(dependency);
    if (dependencyVersion.isDeprecated()) {
      upgradeDependency(dependency);
    }
  })
}

function updateDeprecatedDependencies(dependicies: Dependency[]) {
  dependicies.filter(isDeprecatedDependency).forEach(upgradeDependency);
}

function isDeprecatedDependency(dependency: Dependency) {
  const dependencyVersion = getDependencyVersion(dependency);
  return dependencyVersion.isDeprecated();
}

Enums podem ajudá-lo a documentar o propósito do seu código.

Prática ruim:

const MOBILE_OS= {
  ANDROID: 'android',
  IOS: 'iOS',
}

reactNative.run(MOBILE_OS.ANDROID);

class ReactNative {
  // declaration of React Native
  run(mobileOS) {
    switch (mobileOS) {
      case MOBILE.ANDROID:
        // some logic to be executed 
      case MOBILE.IOS:
        // some logic to be executed
    }
  }
}

enum MOBILE_OS {
  ANDROID,
  IOS,
}

reactNative.run(MOBILE_OS.ANDROID);

class ReactNative {
  // declaration of ReactNative
  run(mobileOS) {
    switch (mobileOS) {
      case MOBILE.ANDROID:
        // some logic to be executed 
      case MOBILE.IOS:
        // some logic to be executed
    }
  }
}

Se você agrupar seu código com um try/catch, isso significa que você acha que pode haver um erro e, portanto, você deve registrar ou fazer algo com o erro.

Prática ruim:

try {
  functionThatMightThrow();
} catch (error) {
  console.log(error);
}

// or even worse

try {
  functionThatMightThrow();
} catch (error) {
  // ignore error
}

import { logger } from './logging'

try {
  functionThatMightThrow();
} catch (error) {
  logger.log(error);
}

Se você tiver código não utilizado, livre-se dele! Ele será mantido em seu histórico de versões se você ainda precisar dele.

function unusedFunction(param: string) {
  // ...
}

function newFunction(param: string) {
  // ...
}

const result = newFunction();

function newFunction(param: string) {
  // ...
}

const result = newFunction();

Use typese precisar de um unionou intersection. Use um interfacese precisar extendsou implements.

Se você estiver interessado, você pode ler mais Interfaces vs Types.

Prática ruim:

interface FrontendConfig {
  // ...
}

interface BackendConfig {
  // ...
}

interface Config {
  // ...
}

//...

type Settings = {
  // ...
}


type FrontendConfig = {
  // ...
}

type BackendConfig = {
  // ...
}

type Config  = FrontendConfig | BackendConfig;

// ...

interface Settings {
  // ...
}

class FrontendSettings implements Settings {
  // ...
}

class BackendSettings implements Settings {
  // ...
}

Podemos falar muito sobre código limpo, um artigo não é suficiente. Se você estiver interessado, também pode ler mais 7 Bad Code Smells In Typescript.

Obrigado pela leitura, espero que você tenha achado esta peça útil. Codificação feliz!

Recursos