Código Limpo para TypeScript - Parte 1

Tendo encontrado o material de acordo com os princípios de código limpo para o TypeScript e lendo-o, decidi retomar sua tradução. Aqui, quero compartilhar alguns trechos desta tradução, já que alguns pontos do código TypeScript puro repetem os mesmos princípios para JavaScript. Não os descreverei aqui. Se for interessante, a tradução para JS já foi publicada no hub (@ BoryaMogila ) ou Você pode se familiarizar com eles na fonte original .



Para começar, vamos descobrir quais são esses princípios de código limpo. Infelizmente, porém, é improvável que você dê uma definição clara de código limpo. Em parte, tudo depende das pessoas, por exemplo, quando você visita o museu, olha a foto e pensa no que é feiura, mas outra pessoa aparece e diz que esplendor. Sim, temos algumas características gerais definidas do mundo em que podemos dizer que uma ou outra é bonita, mas definitivamente não podemos dar uma definição para tudo isso. Então aqui estão apenas alguns pequenos critérios dessa beleza, cuja observância ele escolhe a si mesmo desde então. estas não são as regras que são esculpidas em granito. Estas são apenas recomendações.


Variáveis


Use enum para documentar


O Enam's pode ajudar a documentar seu código. Por exemplo, quando estamos preocupados que nossas variáveis ​​sejam diferentes dos valores.


Ruim:


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

Bom:


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

Funções


Evitar verificação de tipo


O TypeScript é um superconjunto da sintaxe JavaScript e adiciona verificações de tipo estático adicionais ao idioma. Sempre prefira especificar tipos de variáveis, parâmetros e valores de retorno para aproveitar ao máximo o TypeScript. Isso facilita a refatoração futura.


Ruim:


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

Bom:


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

Use iteradores e geradores


Use geradores e iteradores ao trabalhar com coleções de dados usadas como um fluxo.
Existem várias razões para isso:


  • separa o objeto chamado da implementação do gerador no sentido de que o objeto chamado decide quantos elementos
    tem para acesso
  • execução lenta, itens são passados ​​sob demanda
  • suporte interno para elementos de iteração usando for-of sintaxe for-of
  • iteradores permitem implementar padrões de iteradores otimizados

Ruim:


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

Bom:


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

Existem bibliotecas que permitem trabalhar com iteradores da mesma maneira que com suas próprias matrizes, encadeando métodos como map , slice , forEach , etc. Veja o exemplo de itiriri para manipulação avançada de iteradores (ou itiriri-async para manipular iteradores assíncronos).


 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 e estruturas de dados


Use getters e setters


O TypeScript suporta a sintaxe de getters e setters. Usar getters e setters para acessar dados do objeto é muito melhor do que acessar diretamente suas propriedades. "Porque?" você pergunta. Aqui está uma lista de razões:


  • Se você deseja implementar mais do que apenas acessar uma propriedade, é necessário alterar a implementação em um único local, e não em todo o código
  • A validação é fácil de implementar no nível de implementação set
  • Encapsulamento do estado interno
  • Fácil de adicionar registro e tratamento de erros no nível do getter e setter
  • Você pode carregar preguiçosamente propriedades do seu objeto, por exemplo, do servidor

Ruim:


 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; 

Bom:


 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; 

Crie objetos com campos privados / seguros


O TypeScript oferece suporte a meios public (padrão) , protected e private de acesso às propriedades da classe.


Ruim:


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

Bom:


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

Caros leitores, que princípios você usa ao usar o TypeScript?


Para continuar ...

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


All Articles