Conhecendo TypeScript!

Glaucia Lemos
15 min readJan 11, 2017

--

Olá pessoal tudo bem? Como vão todos? Vi que os últimos 2 posts tiveram grande sucesso e dando continuidade, hoje estarei escrevendo sobre TypeScript. Com certeza se você é um desenvolvedor Front-End ou Back-End, já deve ter ouvido falar sobre o TypeScript. Caso nunca tenha escutado, não tem problema, a intenção desse artigo é justamente integrar todos — tantos os que já ouviram falar ou não, sobre esse super set do Javascript. Prepare a pipoca e o guaraná porque vamos ter bastante coisa para falar aqui hoje! :D

Bom… como já comentado acima, o TypeScript é uma linguagem que compila JavaScript projetado para ajudar os desenvolvedores a codificar desde códigos mais simples até mais complexos. Tanto que o TypeScript herda muitos conceitos de programação de linguagens como C# e Java. Podemos trabalhar com classes, heranças, tipagem de tipos tudo dentro do conceito Javascript.

Esse tutorial será bem dummie (bem fácil) com o objetivo de mostrar o principais conceitos e features do TypeScript. Durante esse post estarei disponibilizando os códigos de exemplo com comentários para que seja de fácil compreensão a todos! Estarei no final desse artigo disponibilizando o código fonte no repositório do GitHub. Então, vamos nessa! :D

Benefícios em usar o TypeScript

Talvez alguns se perguntem: “Puxa, o JavaScript já é uma linguagem muito boa e do jeito que ele já é, então…. porque eu deveria aprender TypeScript?? Tecnicamente falando, realmente não há a necessidade em aprender TypeScript para ser um bom desenvolvedor. Tanto que na sua grande maioria todos fazem um excelente trabalho sem o uso do TypeScript. Mas, trabalhar com o TypeScript pode trazer excelentes benefícios para o desenvolvedor. Vejamos alguns desses benefícios:

  • Devido à sua tipagem estática, o código escrito em TypeScript é mais previsível e é mais fácil de poder debbugar o código;
  • Torna a organização do código de fácil leitura para códigos de grande complexidade, graças aos módulos, namespaces e claro que não podemos esquecer o forte apoio ao OOP (Programação Orientada a Objetos);
  • Typescript permite que no momento que realiza a etapa de compilação do Javascript que retorna todos os erros antes que eles atinjam em tempo de execução evitando assim “quebrar” o código antes que seja executado;
  • E para aqueles que desenvolvem código no lado do Front-End, o Angular 2 virá integrado com os recursos do TypeScript. O que facilitará o desenvolvimento da parte dos views.

Acho que já é benefício suficiente para dizer aqui, não é mesmo?!

O último ponto comentado acima é um dos mais importantes para muitos desenvolvedores, uma vez que o Angular 2 é um dos frameworks do momento. Embora muitos desenvolvedores poderão desenvolver os seus códigos em Angular 2 sem a necessidade de usar o TypeScript. Porém, na sua grande maioria, os tutoriais que vocês encontrarão na internet, inclusive no próprio site oficial do Angular 2 [ AQUI ] encontrarão exemplos de Angular 2 + TypeScript. Assim que isso permitirá que muitas pessoas com o passar dos anos (daqui para frente), incluindo comunidades e fóruns, começam a usar e debater mais sobre o TypeScript.

Bom, agora vamos colocar a mão na massa e vamos começar a desenvolver! ;)

Instalando TypeScript

Para desenvolver os códigos abaixo será necessário instalar o Node.Js e o Npm. Caso não tenha instalado na sua máquina basta realizar o download AQUI.

A melhor maneira de instalar o TypeScript é por meio do Npm. Usando o comando abaixo iremos instalar o pacote do TypeScript de maneira global, nos permitindo compilar todos os nossos projetos que iremos desenvolver aqui. Com isso, abre o terminal na sua máquina e digite o seguinte comando abaixo:

$ npm install -g typescript

Bom… após executar o comando acima, vamos verificar se o TypeScript foi devidamente instalado. Para sabermos, digite o comando abaixo:

$ tsc -v

Ao digitar o comando acima nos apresentará a versão instalada.

Se aparecer a versão é porque foi devidamente instalado! Se tudo no seu ambiente estiver certinho então: Show! Vamos prosseguir! :D

IDE’s com Suporte para TypeScript

O TypeScript é um projeto open source, mas que ao mesmo tempo é mantido e desenvolvido pela Microsoft. E anteriormente era somente suportado para a plataforma Visual Studio. MAS…. a situação melhorou e agora há muitos outros editores de texto e IDE’s que nativamente através de plugins, oferecem suporte para a sintaxe para o TypeScript. E em muitas IDE’s nos permitem ter auto-complete, erros de capturas e até mesmo compiladores embutidos para Ts! Que beleza hein!!

Aqui vão uma lista de algumas IDE’s que tem suporte para o TypeScript:

Para os códigos desenvolvidos estarei utilizando o Visual Code. Gosto dele e é uma opção pessoal ;)

Compilação para JavaScript

Os arquivos gerados em Typescript seguem com a seguinte extensão: .ts (ou .tsx para JSX) que não tem como usar diretamente no navegador e precisam ser “traduzidos” ou compilados para .js primeiramente. O processo dessa compilação pode ser feito de diversas maneiras:

  • 1) Através da linha de comando;
  • 2) Ou diretamente no Visual Studio ou alguns outros IDE’s e editores de texto;
  • 3) Ou usando task runners automatizados como o Gulp, por exemplo.

Bom.. para que seja de fácil entendimento a todos… vamos usar a segunda opção usando uma IDE. Nesse caso, estarei usando o Visual Code.

Com o Visual Code aberto crie um arquivo chamado: main.ts. Vamos usar o código que está na própria documentação do site do TypeScript. Digite o código abaixo:

function apresentar(pessoa) {
return "Olá, " + pessoa;
}
var usuario = "Glaucia Lemos";document.body.innerHTML = apresentar(usuario);

Agora.. para que compilemos esse código… abre o terminal e vá até o diretório do projeto e digite o seguinte comando abaixo e veja depois o que irá acontecer!! :D

Agora abre a sua IDE e perceba o que aconteceu….

Ao executar o comando > tsc main.ts foi gerado/compilado um arquivo main.js! Incrível não é mesmo! Vamos dar continuidade!

Uma Linguagem do Tipo Estático! :D

Um dos pontos mais interessantes do Typescript é o suporte para tipo estático. O que isso quer dizer? Isso significa que você pode declarar os tipos de variáveis e o compilador se certificará se os tipos atribuídos estão corretos. Se as declarações de tipo forem omitidas, elas serão inferidas automaticamente no seu código. Confuso não é? Bom… vocês irão entender agora!! ;)

Aqui vai um outro exemplo. Qualquer variável, argumento de função ou valor de retorno pode ter o seu tipo definido:

/**
* Arquivo: hamburger.ts
* Data: 08/11/2016
* Author: Glaucia Lemos
*
*/
var hamburger: string = 'hamburger', //Tipo string
calorias: number = 300, //Tipo Numérico
sabor: boolean = true //Tipo Booleano
/** Opcionalmente você pode omitir o tipo de declaração. Por exemplo:
* Ex.: var hamburger = 'hamburger'
*/
/** A Função espera o retorno do tipo string e inteiro.
* Mas não retornará nada uma vez que o tipo da função está declarada como 'void'
*/
function pedido (comida: string, energia: number): void {
console.log(" Essa " + comida + " tem " + energia + " calorias!");
}
pedido(hamburger, calorias);

Agora vamos compilar esse arquivo e vejamos o que irá acontecer….

/**
* Arquivo: hamburger.js
* Data: 08/11/2016
* Author: Glaucia Lemos
*
*/
var hamburger = 'hamburger',
calorias = 300,
sabor = true;
function pedido(comida, energia) {
console.log(" Essa " + comida + " tem " + energia + " calorias!");
}
pedido(hamburger, calorias);

Observem que os tipos do arquivo gerado em .js foram totalmente removidos. Mas, se nós tentarmos realizar alguma coisa ilegal, quando formos compilar no terminal, o ‘tsc’ irá nos avisar que ocorreu um erro no nosso código. Por exemplo:

var hamburger: string = 'hamburger', //Tipo string
calorias: number = 300, //Tipo Numérico
sabor: boolean = 'Eu não gostei desse sabor...'

Notem que ao tentar compilar, nos apresentará o erro informando que o tipo ‘sabor’ é booleano e não uma string…

Agora… veja esse outro exemplo, quando tentamos passar algum argumento errado para uma função:

function pedido (comida: string, energia: number): void {    console.log(" Essa " + comida + " tem " + energia + " calorias!");
}
//Notem aqui que os argumentos não irão combinar com os parâmetros passados na função:
pedido("Quero um 3x Burger!!", "E um pouco de Cheddar também");

Vejam o erro ao tentarmos executar o código:

Veja agora os tipos de dados mais comuns usados no TypeScript:

  • Number: todos valores numéricos são representados por tipo number. Não há definições separadas para: inteiros, floats ou outros.
  • String: é do tipo texto. E podem ser escritos com aspas simples ‘’ ou aspas duplas “”.
  • Boolean: true ou false. Se usar 0 ou 1 irá causar um erro de compilação.
  • Any: uma variável com esse tipo pode ter uma variável setada para string, number ou qualquer outra coisa;
  • Arrays: há duas possibilidades de sintaxes: my_arr: number[]; ou my_arr: Array;
  • Void: usado em funções que não retornam valores.

Sinta-se à vontade para dar uma olhada na lista de os tipos disponvéis na documentação do TypeScript AQUI.

Lembrando que é a prática junto com estudo que te levará a perfeição. Então… não se limita aos tipos listados aqui… e procure fazer os exemplos da documentação. ;)

Uso de Interfaces em TypeScript

O uso de Interfaces no Typescript são usados para verificar se um determinado objeto se encaixa em uma determinada estrutura. Definindo uma interface, podemos nomear uma combinação específica de variáveis, certificando-se de que essas variáveis estarão sempre juntas. Quando são traduzidas para o JavaScript, as interfaces desaparecem — o seu único objetivo é de ajudar na fase de desenvolvimento. Lindo não é mesmo?!

Aqui vai um exemplo, onde definimos uma interface simples que verifica os argumentos de uma função:

/**
* Arquivo: comida.ts
* Data: 08/11/2016
* Author: Glaucia Lemos
*
*/
//Aqui estamos definindo nossa interface chamada: 'Comida'
// a qual contem propriedades e seus tipos:
interface Comida {
nome: string;
calorias: number;
}
/** Aqui estamos dizendo que a nossa função espera um objeto que cumpre
* com a interface 'Comida'.
* Desta forma, sabemos que as propriedades de que necessitamos estarão sempre disponíveis
*/
function pedido(comida: Comida): void{
console.log("Seu pedido " + comida.nome + " tem " + comida.calorias + " calorias.");
}
/** Nós aqui definimos um objeto que tem todas as propriedades que a interface 'Comida' espera.
* Notem que os tipos serão inferidos automaticamente.
*/
var sorvete = {
nome: "sorvete",
calorias: 200
}
pedido(sorvete);

A ordem das propriedades não importa e não afetará no momento em que formos compilar o nosso código. Nós só precisamos das propriedades requeridas para estar presentes para os tipos certos declarados. Se alguma coisa estiver faltando ou algum tipo de dado errado ou nomeado de forma diferente, o compilador irá nos avisar. ;)

/**
* Arquivo: comida.ts
* Data: 08/11/2016
* Author: Glaucia Lemos
*
*/
interface Comida {
nome: string;
calorias: number;
}
function pedido(comida: Comida): void {
console.log("Seu pedido " + comida.nome + " tem " + comida.calorias + " calorias.");
}
var sorvete = {
noeame: "sorvete",
calorias: 200
}
pedido(sorvete);

Nesse caso aqui nos avisará que o parâmetro ‘nome’ não está escrito devidamente correto.

Há muitas outras coisas envolvidas sobre o uso de interfaces em TypeScript. Com isso, recomendo novamente que deem uma olhada sobre o tema na documentação do TypeScript e procurem fazer os exemplos listados lá! AQUI.

Classes e POO em TypeScript?! Como assim?! :) :)

Quando desenvolvemos aplicações de grande escala, o estilo de programação orientado a objetos sempre será a escolha de muito desenvolvedores. Principalmente para adeptos a linguagens como Java e C#.

Pensando nisso, o TypeScript oferece um sistema de classes muito parecida e semelhante das linguagens citadas acima, a qual está incluída: heranças, classes abstratas, implementações de interfaces, getters & setters e muito mais. Que beleza não é mesmo! :D

Sem contar que, desde a atualização mais recente do JavaScript (ECMAScript 2015), as classes nativas do Vanilla JS (que é o JavaScript puro — mais informações AQUI) podem ser usadas sem o TypeScript. A implementação dos dois são muito parecidas, mas tem as suas diferenças. O TypeScript é um pouco mais rigoroso. ;)

Bom…. vamos continuar com o nosso exemplo de comida…. e como declaramos classes em TypeScript:

/**
* Arquivo: menu.ts
* Data: 11/01/2017
* Author: Glaucia Lemos
*
*/
class Menu {
/* Nossas propriedades
que por default serão públicas (public), mas que ao mesmo podem ser também
private ou protected */
itens: Array<string> //aqui estamos declarando um array... uma vez que vamos ter inúmeros menus.. :)
paginas: number; //aqui estamos definindo a quantidade de páginas terá o menu.
/**
* Aqui estamos definindo um construtor simples
*/
constructor(lista_itens: Array<string>, total_paginas: number) {
this.itens = lista_itens;
this.paginas = total_paginas;
}
/* Métodos */
lista(): void {
console.log("Nosso menu de Hoje é:");
for(var i = 0; i < this.itens.length; i++) {
console.log(this.itens[i]);
}
}
}
/* Aqui vamos criar uma nova instância para a classe Menu */
/* Lembrando que aqui devemos passar 2 parâmetros: os itens da lista e o número de páginas;) */
var menuDomingo = new Menu(["Hamburger", "CheeseCake", "Bolo de Cenoura", "Espaguete"], 1)
/* E aqui finalmente, fazermos a chamada do método :D * */
menuDomingo.lista();

Todos aqui que já programaram alguma vez em Java ou C# podem notar que não há diferença nenhuma aqui. Como podem observar no código acima é POO puro!! :D Que lindo não é mesmo?! Dá até vontade de….

E o mesmo procede quando trabalhamos com herança em TypeScript. Veja o exemplo abaixo:


/**
* Arquivo: refeicaoPratoFeito.ts
* Data: 11/01/2017
* Author: Glaucia Lemos
*
*/
/* a palavra reservada: extends - indica que estamos realizando herança com a classe Menu */
class RefeicaoPratoFeito extends Menu {
/**
* Aqui vamos definir um novo construtor para a nossa classe
*/
constructor(lista_itens: Array<string>, total_paginas:number) {
/* Porém nesse caso, como estamos trabalhando com herança,
precisamos da palavra reservada: super para que a classe subtende que este construtor
é parente da classe Menu. */
super(lista_itens, total_paginas);
}
/* Assim como as propriedades, os métodos também serão herdados da classe pai.
Porém, nós iremos subscrever esse método e para isso vamos usar o 'override' :D */
lista(): void {
console.log("Nosso menu especial de hoje para quem quer pagar mais barato: ");
for(var i = 0; i < this.itens.length; i++) {
console.log(this.itens[i]);
}
}
}
/** Criaremos uma nova instância para a nossa classe: refeicaoPratoFeito */
var menuRefeicaoPratoFeito = new RefeicaoPratoFeito(['Arroz', 'Feijão', 'Batata Frita', 'Cebola', 'Tomate', 'Farofa'], 1);
/** Nesse caso aqui o log de mensagem começará com a mensagem especial */
menuRefeicaoPratoFeito.lista();

Bom…. novamente, caso queiram obter mais informações sobre Classes e Heranças em TypeScript dêem uma olhada na documentação sobre o assunto: AQUI.

Uso de Genéricos em TypeScript

Os genéricos são modelos que permitem que a mesma função aceite argumentos de vários tipos diferentes. Criar componentes reutilizáveis usando a estrutura genérica é a melhor maneira do que usarmos o tipo de dado do TypeScript ‘any’. Porque o genéricos preservarão os tipos das variáveis e tipos de informações que entram e saem deles.

Aqui abaixo há um exemplo bem simples e rápido do que seria um determinado script que recebe um argumento e retorna uma matriz contendo o mesmo argumento:


/**
* Arquivo: exemploGenerics.ts
* Data: 11/01/2017
* Author: Glaucia Lemos
*
*/
/* O <T> após a função simboliza que é uma função genérica.
Quando chamamos a função, cada instância de T será substituída pelo
tipo atual fornecido. */
/** Aqui ele irá receber um argumento do tipo T,
* Depois retorna uma matriz do tipo T
*/
function funcaoGenerica<T>(arg: T): T[] {
var arrayT: T[] = []; //Aqui estamos criando um array do tipo T.
arrayT.push(arg); //Agora o 'arrayT receberá o 'arg'
return arrayT;
}
var arrayString = funcaoGenerica<string>("Atchim!!!!!");
console.log(arrayString[0]); //"Atchim"
console.log(typeof arrayString[0]); //string
var arrayNumero = funcaoGenerica(30);
console.log(arrayNumero[0]); //30
console.log(typeof arrayNumero[0]); //number

Confuso não? Calma que eu vou explicar aqui o que está acontecendo….

Na primeira vez que fazemos a chamada da função, definimos manualmente o tipo para string. Isso não será necessário, uma vez que o compilador pode notar qual o argumento que foi passado e decidir automaticamente qual será o o tipo que melhor se adequa ao programa, assim como na segunda chamada. Embora não seja obrigatório, é considerado uma boa prática fornecer o tipo de dados, caso não definimos…. o compilador irá falhar na execução do código tentando adivinhar qual é o tipo de dado.

Na documentação do TypeScript, contém exemplos muito mais avançados sobre tipos Genéricos. Sintam-se novamente à vontade em realizar os exemplos e executá-los no seu ambiente seguindo a documentação: AQUI.

E….. Módulos!

Um outro importante conceito quando se trabalha com grandes aplicações é a modularidade. Ter o seu código dividido em muitos pequenos componentes reutilizáveis ajudará o seu projeto a ficar muito mais organizado e compreensível para futuros desenvolvedores. Em contra partida em vez de ter um único arquivo contendo zilhões de linhas de código que faz tudo.

O TypeScript introduz uma sintaxe que nos facilita sobre esse assunto. Uma vez que nos permite exportar e importar módulos. MAS, não consegue lidar com a ligação entre arquivos. Para que isso seja possível, devemos habilitar os módulos externos, ao fazermos isso, o TS confiará nas bibliotecas de terceiros, que nesse caso, como por exemplo: require.js para aplicativos do navegador e CommonJs para Node.Js. Vamos dar uma olhada num exemplo bem simples de uso de Módulos em TypeScript utilizando require.js.

Vamos ter 2 arquivos. Um para exportar uma função e o outro para importar e chamar a função.

  • export.ts

/**
* Arquivo: export.ts
* Data: 11/01/2017
* Author: Glaucia Lemos
*
*/
var olaMundo = function(): void {
console.log("Olá!!!!");
}
export = olaMundo;
  • import.ts

/**
* Arquivo: import.ts
* Data: 11/01/2017
* Author: Glaucia Lemos
*
*/
import olaMundo = require('./export');
olaMundo();

Agora, nós vamos precisar realizar o download do ‘require.js’ e incluí-lo a tag de script — Exemplo AQUI. A última etapa é compilar os nossos dois arquivos .ts. Um parâmetro extra precisará ser adicionado para dizer ao TypeScript que estamos construindo módulos para ‘require.js’, ao contrário do CommonJs. Depois de seguir as orientações do site… digite o comando abaixo:

> tsc --module amd *.ts

O uso de módulos é um assunto um pouco complexo e é algo que não pretendo me aprofundar nesse tutorial. Caso deseja ter mais detalhes, leia sobre o assunto na documentação do TypeScript: AQUI

Em Breve: TypeScript 2.0! Como assim?!

Sim meus amiguinhos e amiguinhas já foi lançado a versão 2.0 do TypeScript e segue evoluindo (até o momento desse post.. já se encontra na versão 2.1). E a versão já está disponível para experimentá-lo agora: AQUI.

Mas o que há de novo nessa nova versão? Bom… ele introduz alguns novos conceitos úteis como:

  • Novo sistema melhorado para poder obter arquivos diretamente via npm;
  • Análise do tipo de fluxo de controle que detecta os erros anteriormente perdidos pelo compilador na antiga versão;
  • Algumas inovações na sintaxe para poder realizar exportação e importação de módulos;

Claro que há outras novidades… Mas uma delas que é a mais aguardada é a capacidade de controlar fluxos de funções assíncronas em um bloco async/await. Provavelmente já disponível na futura atualização 2.1

Gostou do TypeScrit? Então vou recomendar algumas leituras que são de suma importância para aprofundar os seus conhecimentos sobre o assunto:

  • Namespaces: aqui
  • Enums: aqui
  • Escrevendo JSX em TypeScript: aqui
  • Tipos Avançados: aqui

Por favor, não se limite a esse post. Há uma documentação cheia de exemplos e muito bem explicada pelo próprio site do TypeScript e diversos e inúmeros sites sobre assunto. Eu alto recomendo essa video aula do Erick Wendel — que trabalha na FCamara, que realizou um treinamento sobre TypeScript através do site MVA. Terminando o treinamento de quebra ganha uma certificação da Microsoft.

  • [Video-Aula] Introdução ao NodeJS com Typescript no Visual Studio Code: AQUI
  • Site do Erick Wendel: AQUI

Bom.. por hoje é tudo pessoal…. novo ano e pretendo uma vez por semana estar escrevendo artigos por aqui. Ando um pouco enrolada, uma vez que estou na luta atrás de um trabalho. Mas, espero que retorne aqui para dar uma boa notícia a todos! E a notícia sobre o retorno do meu canal do Youtube! :D

p.s.: códigos desenvolvidos: AQUI

Beijos a todos! E fui! ❤ ❤

--

--

Glaucia Lemos
Glaucia Lemos

Written by Glaucia Lemos

Developer Advocate 🥑 in JavaScript/TypeScript at @Microsoft | Open Source | Geek & Girl

No responses yet