
Trabalhando com qualquer linguagem de programação, rastreamos exceções e lemos o código linha por linha para encontrar o problema e como corrigi-lo. O TypeScript permite automatizar essa parte frustrante do processo de desenvolvimento.
TypeScript, ao contrário de muitas outras linguagens digitadas, é orientado a aplicativos. Ele apresenta novos conceitos que permitem expressar ideias de forma mais sucinta e precisa e criar aplicativos modernos escalonáveis ​​e seguros com facilidade.
Boris Cherny ajuda a entender todas as nuances e recursos do TypeScript, ensina a eliminar erros e dimensionar o cĂłdigo.
Estrutura do livro
Eu (o autor) tentei dar a você uma compreensão teórica de como o TypeScript funciona e uma boa quantidade de conselhos práticos de codificação.
TypeScript Ă© uma linguagem prática, entĂŁo teoria e prática complementam-se principalmente no livro, mas os dois primeiros capĂtulos cobrem principalmente a teoria e, no final, apenas a prática Ă© apresentada.
Cobriremos o básico, como o compilador, o verificador de tipo e os prĂłprios tipos. A seguir, discutiremos suas variedades e operadores e, em seguida, passaremos para tĂłpicos avançados, como especificações do sistema de tipos, tratamento de erros e programação assĂncrona. Por fim, mostrarei como usar o TypeScript com suas estruturas favoritas (front-end e back-end), migrar um projeto JavaScript existente para o TypeScript e executar um aplicativo TypeScript em produção.
A maioria dos capĂtulos termina com um conjunto de exercĂcios. Experimente vocĂŞ mesmo para obter uma melhor compreensĂŁo do material. As respostas para eles estĂŁo disponĂveis aqui .
Migração em estágios de JavaScript para TypeScript
O TypeScript foi projetado com a interoperabilidade do JavaScript em mente. Portanto, embora nĂŁo seja completamente indolor, migrar para o TypeScript ainda Ă© uma experiĂŞncia agradável, permitindo que vocĂŞ transforme seu arquivo de base de cĂłdigo por vez, obtenha um nĂvel mais profundo de segurança e efetue o commit apĂłs o commit e surpreenda seu chefe e colegas de trabalho como o cĂłdigo estaticamente digitado pode ser poderoso. ...
Em um alto nĂvel, a base de cĂłdigo deve ser completamente escrita em TypeScript e fortemente tipada, e as bibliotecas JavaScript de terceiros das quais vocĂŞ depende devem ser de boa qualidade e ter seus prĂłprios tipos fortes. Seu processo de codificação será atĂ© 2x mais rápido com detecção de erros em tempo de compilação e um rico sistema de preenchimento automático TypeScript. Para obter um resultado de migração bem-sucedido, serĂŁo necessárias algumas pequenas etapas:
- Adicione TSC ao projeto.
- Comece verificando os tipos de cĂłdigo JavaScript existentes.
- Mova o cĂłdigo JavaScript para TypeScript arquivo por arquivo.
- Instale declarações de tipo para dependências. Ou seja, alocar tipos para dependências que não os possuem ou escrever declarações de tipo para dependências não tipadas e enviá-las de volta para DefinitelyTyped1.
- Habilite o modo estrito para a base de cĂłdigo.
Este processo pode demorar um pouco, mas vocĂŞ verá imediatamente ganhos de segurança e desempenho e outros benefĂcios posteriormente. Vamos dar uma olhada nas etapas listadas.
Etapa 1: adicionar TSC
Ao trabalhar com uma base de código que combina TypeScript e JavaScript, primeiro deixe o TSC compilar os arquivos JavaScript junto com os arquivos TypeScript nas configurações tsconfig.json:
{
"compilerOptions": {
"allowJs": true
}
Essa mudança por si só permitirá que o TSC seja usado para compilar o código JavaScript. Simplesmente adicione TSC ao processo de construção e execute cada arquivo JavaScript por meio dele ou continue executando os arquivos JavaScript legados por meio do processo de construção e novos arquivos TypeScript por meio do TSC.
Com allowJs definido como verdadeiro, o TypeScript nĂŁo irá typecheck no cĂłdigo JavaScript atual, mas irá transpilar esse cĂłdigo para ES3, ES5 ou a versĂŁo que está definida como destino no arquivo tsconfig.json usando o sistema de mĂłdulo que vocĂŞ solicitou (no mĂłdulo arquivo json). A primeira etapa foi concluĂda. Comprometa-se e dĂŞ um tapinha nas costas - sua base de cĂłdigo agora está usando TypeScript.
Etapa 2a: habilitar a verificação de tipo de JavaScript (opcional)
Agora que o TSC está processando JavaScript, por que nĂŁo verificar seus tipos? Mesmo que nĂŁo haja anotações de tipo explĂcitas, lembre-se de que o TypeScript pode inferir tipos para o cĂłdigo JavaScript da mesma forma que para o cĂłdigo TypeScript. Inclua a opção necessária em tsconfig.json:
{
"compilerOptions": {
"allowJs": true,
"checkJs": true
}
Agora, sempre que o TypeScript compilar um arquivo JavaScript, ele tentará inferir e validar os tipos, assim como faz para o código TypeScript.
Se sua base de código for grande e quando você habilitar checkJs, ele encontrar muitos erros de uma vez, desative-o. Em vez disso, habilite a verificação de arquivo JavaScript um por vez, adicionando a diretiva // @ ts-check (um comentário normal na parte superior do arquivo). Ou, se arquivos grandes apresentarem vários erros que você ainda não deseja corrigir, deixe checkJs habilitado e adicione a diretiva // @ ts-nocheck para esses arquivos.
O TypeScript nĂŁo pode inferir tipos para tudo (por exemplo, ele nĂŁo infere tipos para parâmetros de função), portanto, inferirá muitos tipos em JavaScript como qualquer um. Se vocĂŞ tiver o modo estrito ativado em tsconfig.json (recomendado), pode preferir permitir qualquer um implĂcito durante a migração. Adicione o seguinte ao tsconfig.json:
{ "compilerOptions": { "allowJs": true, "checkJs": true, "noImplicitAny": false }
Lembre-se de ativar noImplicitAny novamente quando terminar de migrar a maior parte do seu cĂłdigo para o TypeScript. Isso provavelmente encontrará muitos insetos perdidos (a menos que vocĂŞ seja Zenidar, um discĂpulo da bruxa JavaScript Bavmorda, que pode verificar o tipo com o poder de sua mente com uma poção de absinto).
Quando o TypeScript executa o cĂłdigo JavaScript, ele usa um algoritmo de inferĂŞncia mais suave do que o cĂłdigo TypeScript. Nomeadamente:
- Todos os parâmetros de função são opcionais.
- Os tipos de propriedades de funções e classes são inferidos com base em seu uso (em vez de ter que ser declarado com antecedência):
class A { x = 0 // number | string | string[], . method() { this.x = 'foo' } otherMethod() { this.x = ['array', 'of', 'strings'] } }
- Depois de declarar um objeto, classe ou função, vocĂŞ pode atribuir propriedades adicionais a ele. Nos bastidores, o TypeScript faz isso gerando um namespace apropriado para cada declaração de função e adicionando automaticamente uma assinatura de Ăndice a cada literal de objeto.
Etapa 2b: adicionar anotações JSDoc (opcional)
Você pode estar com pressa e só precisa adicionar uma anotação de tipo para uma nova função que foi adicionada a um arquivo JavaScript antigo. Você pode usar a anotação JSDoc para fazer isso até que você possa converter este arquivo para TypeScript.
VocĂŞ provavelmente já viu JSDoc antes. Esses sĂŁo comentários como este no topo do cĂłdigo com anotações começando com @, comoparam, @returns e assim por diante. TypeScript entende JSDoc e o usa como entrada para o verificador de tipo junto com anotações de tipo explĂcitas.
Suponha que você tenha um arquivo de serviço de 3.000 linhas (sim, eu sei, seu "amigo" o escreveu). Você adiciona uma nova função de serviço a ele:
export function toPascalCase(word) {
return word.replace(
/\w+/g,
([a, ...b]) => a.toUpperCase() + b.join('').toLowerCase()
)
}
Sem uma conversão completa de utils.js em TypeScript, o que certamente revelará um monte de bugs, você só pode anotar a função toPascaleCase, criando uma pequena ilha de segurança em um mar de JavaScript não tipado:
/**
* @param word {string} .
* @returns {string} PascalCase
*/
export function toPascalCase(word) {
return word.replace(
/\w+/g,
([a, ...b]) => a.toUpperCase() + b.join('').toLowerCase()
)
}
Sem essa anotação, JSDoc TypeScript inferiria o tipo toPascaleCase como (palavra: qualquer) => string. Agora, ao compilar, ele saberá que o tipo toPascaleCase é (palavra: string) => string. E você obtém documentação útil.
Para obter informações mais detalhadas sobre anotações JSDoc, visite o Wiki do TypeScript (https://github.com/Microsoft/TypeScript/wiki/JSDoc-support-in-JavaScript).
Etapa 3: renomear arquivos para .ts
Depois de adicionar o TSC ao seu processo de construção e, opcionalmente, começar a verificar os tipos e anotar o cĂłdigo JavaScript sempre que possĂvel, Ă© hora de mudar para o TypeScript.
Arquivo por arquivo, atualize as permissões de arquivo de .js (ou .coffee, es6, etc.) para .ts. Imediatamente após renomear os arquivos no editor, você verá amigos ondulados em vermelho, indicando erros de tipo, casos perdidos, verificações nulas esquecidas e erros de digitação em nomes de variáveis. Existem duas maneiras de removê-los.
- . , , , . checkJs, noImplicitAny tsconfig.json, any , , JavaScript .
- .ts tsconfig.json ( strict false), . any, . . , strict (noImplicitAny, noImplicitThis, strictNullChecks . .), . ( .)
, TODO any any, . , :
// globals.ts type TODO_FROM_JS_TO_TS_MIGRATION = any // MyMigratedUtil.ts export function mergeWidgets( widget1: TODO_FROM_JS_TO_TS_MIGRATION, widget2: TODO_FROM_JS_TO_TS_MIGRATION ): number { // ... }
Ambas as abordagens sĂŁo bastante relevantes e cabe a vocĂŞ decidir qual delas Ă© preferĂvel. TypeScript Ă© uma linguagem digitada passo a passo projetada desde o inĂcio para interagir com JavaScript nĂŁo digitado da maneira mais segura possĂvel. NĂŁo importa se vocĂŞ interage com JavaScript nĂŁo digitado ou TypeScript fracamente tipado, o TypeScript fortemente tipado sempre garantirá que a interação seja o mais segura possĂvel.
Etapa 4: ative o rigor
Uma vez que uma massa crĂtica de cĂłdigo JavaScript tenha sido portada, vocĂŞ desejará torná-lo tudo-em-um seguro usando os sinalizadores TSC mais restritos um por um (consulte o ApĂŞndice E para uma lista completa de sinalizadores).
Quando terminar, você pode desligar os sinalizadores TSC responsáveis ​​por interagir com JavaScript, confirmando que todo o seu código está escrito em TypeScript fortemente tipado:
{
"compilerOptions": {
"allowJs": false,
"checkJs": false
}
Isso irá expor quaisquer erros de tipo restantes. Corrija-os e obtenha uma base de código segura e sem falhas que a maioria dos engenheiros mais severos do OCaml daria um tapinha nas costas.
Seguir essas etapas o ajudará a ir longe ao adicionar tipos ao código JavaScript que você controla. Mas e os códigos que não são controlados por você? Como os instalados com NPM. Mas antes de estudarmos esta questão, vamos divagar um pouco ...
Encontrar tipos para JavaScript
Quando você importa um arquivo JavaScript de um arquivo TypeScript, o TypeScript procura por declarações de tipo para ele usando o seguinte algoritmo (lembre-se, no TypeScript, "arquivo" e "módulo" são usados ​​alternadamente):
- .d.ts , .js. .js.
, :
my-app/
├──src/
│ ├──index.ts
│ └──legacy/
│ ├──old-file.js
│ └──old-file.d.ts
old-file ( ) index.ts:
// index.ts
import './legacy/old-file'
TypeScript src/legacy/old-file.d.ts ./legacy/old-file. - , allowJs checkJs true, .js ( JSDoc) any.
TSC-: TYPEROOTS ( )
TypeScript node modules/@types , (../node modules/@types . .). .
, typeRoots tsconfig.json , . , TypeScript typings node modules/@types:
{ "compilerOptions": { "typeRoots" : ["./typings", "./node modules/@types"] } }
types tsconfig.json, , TypeScript . , , React:
{ "compilerOptions": { "types" : ["react"] } }
Ao importar um mĂłdulo JavaScript de terceiros (o pacote NPM que vocĂŞ instalou nos mĂłdulos de nĂł), o TypeScript usa um algoritmo ligeiramente diferente:
- Procura uma declaração de tipo local para o módulo e, se houver, a usa.
Por exemplo, sua estrutura de diretĂłrio Ă© semelhante a esta:
my-app /
├──node_modules /
│ └──foo /
├──src /
│ ├──index.ts
│ └──types.d.ts
É assim que type.d se parece .ts:
// types.d.ts declare module 'foo' { let bar: {} export default bar }
Se você importar foo, o TypeScript usará a declaração do módulo externo em types.d.ts como a fonte do tipo:
// index.ts
import bar from 'foo' - package.json, . types typings, .d.ts, , .
- Ou percorrerá os diretórios procurando o diretório node modules / @ types, que contém as declarações de tipo para o módulo.
Por exemplo, vocĂŞ instalou React:
npm install react --save
npm install @ types / react --save-dev
my-app /
├──node_modules /
│ ├── @ types /
│ │ └──react /
│ └──
react / ├──src /
│ └──index.ts
Ao importar React, o TypeScript encontrará o diretório @ types / react e o usará como a fonte das declarações de tipo para ele:
// index.ts
import * as React from ' react ' - Caso contrário, ele irá para as etapas 1–3 do algoritmo de pesquisa de tipo local.
Listei alguns passos, mas vocĂŞ vai se acostumar com eles.
Sobre o autor
Boris Cherny Ă© engenheiro-chefe e lĂder de produto no Facebook. Já trabalhou na VC, AdTech e em uma variedade de startups, a maioria das quais nĂŁo existe hoje. Ele está interessado em linguagens de programação, sĂntese de cĂłdigo e análise estática e se esforça para compartilhar sua experiĂŞncia com produtos digitais com os usuários. Em seu tempo livre, ele organiza reuniões de clube TypeScript em San Francisco e mantĂ©m um blog pessoal - performancejs.com . VocĂŞ pode encontrar a conta GitHub de Boris em github.com/bcherny .
»Mais detalhes sobre o livro podem ser encontrados no site da editora
» Índice
» Excerto
para Habitans 25% de desconto no cupom - TypeScript
ApĂłs o pagamento da versĂŁo em papel do livro, Ă© enviado um e-book para o e-mail.