Como o Typecript me decepcionou e vale a pena?



Antes de começar, quero mencionar que sou um fã do TypeScript. Esta é minha principal linguagem de programação para projetos front-end no React e para qualquer trabalho de back-end que eu faço no Node. Sou totalmente a favor do Typecript, mas há momentos que me incomodam e sobre os quais eu gostaria de contar este artigo.

Eu escrevi exclusivamente no TypeScript nos últimos três anos para muitas empresas diferentes; portanto, na minha opinião, o TypeScript faz pelo menos algo certo ou fecha certas necessidades.

Apesar de suas imperfeições, o TypeScript entrou no front-end de desenvolvimento e ocupa a sétima posição na lista das linguagens de programação mais populares, de acordo com o relatório de habilidades do desenvolvedor do HackerRank .

Qualquer equipe de desenvolvimento, independente de grande ou pequena, escreve ou não em TypeScript, sempre vale a pena por segurança:

  • Verifique se os testes de unidade bem escritos abrangem o máximo de código possível na produção.
  • Use a programação em pares: um par extra de olhos ajudará a capturar coisas mais sérias do que apenas erros de sintaxe
  • Crie qualitativamente um processo de revisão de código e identifique erros que a máquina não consegue encontrar
  • Use o linter - como eslint

Embora o TypeScript adicione um nível adicional de segurança além de tudo isso, mas, na minha opinião, ele está muito atrás de outras linguagens nesse sentido. Eu vou explicar o porquê.

O TypeScript não é um sistema de tipos confiável


Acho que esse pode ser o principal problema do TypeScript, mas primeiro deixe-me determinar o que são sistemas de tipos confiáveis e não confiáveis .

Sistema robusto


Um sistema de tipo confiável garante que seu programa não termine em estados inválidos. Por exemplo, se o tipo estático de uma expressão for string , quando for avaliado em tempo de execução, você terá a garantia de obter apenas a string .

Em um sistema de tipos confiável, você nunca estará em uma situação em que a expressão não corresponda ao tipo esperado, no tempo de compilação ou no tempo de execução.

Obviamente, existem vários graus de confiabilidade, bem como várias interpretações de confiabilidade. O TypeScript é um pouco confiável e captura erros de tipo:

// Type 'string' is not assignable to type 'number' const increment = (i: number): number => { return i + "1"; } // Argument of type '"98765432"' is not assignable to parameter of type 'number'. const countdown: number = increment("98765432"); 

Sistema de tipo inseguro


O texto datilografado relata abertamente que 100% de confiabilidade não é seu objetivo. Até o número "não alvo" 3 na lista "não alvo" do TypeScript afirma claramente:
Ter um sistema do tipo confiável ou "comprovadamente correto" não é nosso objetivo. Em vez disso, buscamos um equilíbrio entre precisão e desempenho.

Isso significa que não há garantia de que a variável seja de um tipo específico em tempo de execução. Eu posso ilustrar isso com o seguinte exemplo um tanto artificial:

 interface A { x: number; } let a: A = {x: 3} let b: {x: number | string} = a; bx = "unsound"; let x: number = ax; // unsound axtoFixed(0); // WTF is it? 

O código acima não funciona, pois sabe-se que ax é um número da interface A. Infelizmente, depois de algumas simulações de reatribuição, ele se transforma em uma string e esse código é compilado, mas com erros no tempo de execução.

Infelizmente, esta expressão compila sem erros:

 axtoFixed(0); 

Que a confiabilidade não é o objetivo da linguagem é provavelmente um dos maiores problemas do TypeScript. Continuo recebendo muitos erros de erro de tempo de execução que o compilador tsc não captura, mas que o compilador teria notado se existisse um sistema de tipo confiável no TypeScript. O TypeScript agora é um pé no campo das linguagens "confiáveis" e o outro no "não confiável". Essa abordagem de meia medida é baseada em qualquer tipo, que discutirei mais adiante.

Estou frustrado pelo fato de o número de testes que eu escrever não ter diminuído com a transição para o TypeScript. Quando comecei, decidi erroneamente que poderia reduzir a rotina onerosa de escrever um grande número de testes de unidade.

O TypeScript desafia o estado atual das coisas, argumentando que a redução dos custos cognitivos ao usar tipos é mais importante que a confiabilidade.

Entendo por que o TypesScript escolheu esse caminho e há uma opinião de que o TypeScript não seria tão popular se a confiabilidade do sistema de tipos fosse 100% garantida. Essa opinião não resistiu ao teste - a linguagem Dart está rapidamente ganhando popularidade, juntamente com o uso generalizado do Flutter. E argumenta-se que a confiabilidade do tipo é o objetivo do Dart.

A insegurança e as várias maneiras pelas quais o TypeScript fornece uma "saída de emergência" devido à digitação forte o tornam menos eficiente e, infelizmente, o tornam "melhor que nada" no momento. Eu ficaria feliz se, à medida que o TypeScript crescesse em popularidade, mais opções de compiladores se tornassem disponíveis, permitindo que usuários experientes lutassem por 100% de confiabilidade.

O TypeScript não garante nenhuma verificação de tipo em tempo de execução


A verificação de tipo em tempo de execução não é o objetivo do TypeScript, portanto, meu desejo provavelmente nunca se tornará realidade. A verificação do tipo em tempo de execução é útil, por exemplo, ao trabalhar com dados JSON retornados de chamadas de API. Seria possível se livrar de toda uma categoria de erros e muitos testes de unidade, se pudéssemos controlar esses processos no nível do sistema de tipos.

Como não podemos garantir nada em tempo de execução, isso pode acontecer facilmente:

 const getFullName = async (): string => { const person: AxiosResponse = await api(); //response.name.fullName may result in undefined at runtime return response.name.fullName } 

Existem algumas bibliotecas auxiliares como io-ts , o que é ótimo, mas isso pode significar que você precisa duplicar seus modelos.

Tipo assustador qualquer e opção estrita


O tipo any significa "any", e o compilador permite qualquer operação ou atribuição de uma variável desse tipo.

O TypeScript funciona bem para pequenas coisas, mas as pessoas tendem a colocar qualquer tipo em qualquer coisa que leve mais de um minuto. Recentemente, trabalhei em um projeto Angular e vi muitos códigos como este:

 export class Person { public _id: any; public name: any; public icon: any; 

O TypeScript permite que você esqueça o sistema de tipos.

Você pode quebrar o tipo de qualquer coisa com qualquer :

 ("oh my goodness" as any).ToFixed(1); // remember what I said about soundness? 

A opção estrita inclui as seguintes opções do compilador, que tornam tudo mais confiável:

  • --strictNullChecks
  • --noImplicitAny
  • --noImplicitThis
  • --alwaysStrict

Há também uma regra eslint @ typescript-eslint / no-explícita-qualquer .

Distribuir qualquer um pode arruinar a confiabilidade do seu código.

Conclusão


Preciso repetir que sou um fã do TypeScript e utilizá-lo no meu trabalho diário, mas sinto que é imperfeito e o hype ao seu redor não é inteiramente justificado. O Airbnb afirma que o TypeScript ajudou a evitar 38% dos erros . Sou muito cético em relação à porcentagem declarada com tanta precisão. O TypeScript não aprimora nem combina todas as práticas existentes de bom código. Eu ainda tenho que escrever uma tonelada de testes. Você poderia argumentar que eu escrevo mais código, então tenho que escrever muitos testes. Continuo recebendo muitos erros de execução inesperados.

O TypeScript oferece apenas verificação básica de tipo, e o fato de a confiabilidade e a verificação de tipo em tempo de execução não serem o seu objetivo deixa o TypeScript no mundo das meias medidas, a meio caminho entre o melhor mundo e o que codificamos agora.

O TypeScript é excelente graças ao bom suporte de IDEs, como vscode, onde obtemos feedback visual durante o processo de impressão.


Erro TypeScript no vscode

O TypeScript também aprimora as alterações de refatoração e quebra de código (como alterações nas assinaturas de métodos) que são identificadas instantaneamente quando o compilador TypeScript é iniciado.
O TypeScript fornece uma boa verificação de tipo e é definitivamente melhor do que nenhuma verificação de tipo ou remoção simples, mas acho que o TypeScript pode ser muito melhor e as opções necessárias do compilador podem agradar aqueles que desejam mais da linguagem.



Inscreva-se no nosso desenvolvedor do Instagram


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


All Articles