Introdução ao TypeScript
TypeScript é um superset open-source do JavaScript desenvolvido pela Microsoft. Ele adiciona tipos estáticos e características de programação orientada a objetos com o objetivo de melhorar a eficiência no desenvolvimento de aplicações JavaScript de grande escala e a manutenibilidade do código. O TypeScript é compilado para JavaScript puro, podendo ser executado em qualquer ambiente que suporte JavaScript.
Principais características:
- Tipagem Estática: Permite especificar tipos para variáveis, parâmetros de funções e valores de retorno, realizando verificações em tempo de compilação.
- Interferência de Tipos: O compilador pode deduzir automaticamente o tipo de uma variável mesmo sem uma anotação explícita.
- Interfaces: Utilizadas para definir a estrutura e o tipo de objetos, garantindo que eles atendam a um contrato específico.
- Classes e Herança: Suporta programação orientada a objetos, permitindo a definição de classes, herança e modificadores de acesso.
- Modularidade: Compatível com a especificação de módulos ES6, permitindo a organização do código em módulos independentes.
- Compatibilidade: Como o TypeScript é um superset do JavaScript, qualquer código JavaScript válido também é válido em TypeScript.
Tipos Fundamentais
Tipo Boolean
Representa um valor lógico verdadeiro (true) ou falso (false).
let carregado: boolean = true;
let visivel: boolean = false;
Tipo Number
Representa todos os tipos numéricos, incluindo inteiros e ponto flutuante. Suporta literais decimais, hexadecimais, binários e octais.
let quantidade: number = 42;
let hexadecimal: number = 0x1A3B;
let binario: number = 0b1010;
let octal: number = 0o745;
Tipo String
Representa dados de texto. Aceita aspas simples (') ou duplas ("), além de template strings delimitadas por crases.
let nome: string = 'Ana';
let sobrenome: string = "Silva";
let mensagem: string = `Olá, ${nome} ${sobrenome}.
Bem-vinda ao sistema.`;
Tipo Array
Pode ser definido de duas formas principais: usando a sintaxe tipo[] ou a sintaxe genérica Array<tipo>.
let notas: number[] = [8, 9, 7.5];
let frutas: Array<string> = ['maçã', 'banana'];
Tipo Tuple
Representa um array com um número fixo de elementos, onde cada elemento pode ter um tipo diferente.
let registro: [string, number];
registro = ['Lucas', 28]; // Correto
// registro = [28, 'Lucas']; // Erro
console.log(registro[0].toUpperCase()); // LUCAS
// console.log(registro[1].toUpperCase()); // Erro
Tuplas podem ter elementos opcionais e rótulos.
const ponto: [x: number, y: number] = [10, 20];
let dados: [string, number?];
dados = ['Teste'];
dados = ['Teste', 123];
Tipo Enum
Oferece uma maneira de dar nomes amigáveis a conjuntos de valores numéricos.
enum NivelLog {
DEBUG,
INFO,
WARN,
ERROR
}
let nivel: NivelLog = NivelLog.INFO;
enum Resposta {
SIM = 1,
NAO = 0
}
let minhaResposta: Resposta = Resposta.SIM;
É possível obter o nome a partir do valor.
enum Cor {
VERMELHO = 1,
VERDE,
AZUL
}
let nomeCor: string = Cor[2];
console.log(nomeCor); // "VERDE"
Tipo Any
Representa um valor de qualquer tipo. Útil para variáveis que não possuem tipo definido em tempo de compilação.
let valor: any = 10;
valor = "texto";
valor = true;
Tipo Void
Representa a ausência de um tipo de valor, comumente usado como tipo de retorno de funções que não produzem um valor.
function registrarAcao(acao: string): void {
console.log(`Ação: ${acao}`);
}
Tipo Null e Undefined
Cada um tem seu próprio tipo correspondente.
let naoDefinido: undefined = undefined;
let nulo: null = null;
Tipo Never
Representa o tipo de valores que nunca ocorrem.
function lancarErro(mensagem: string): never {
throw new Error(mensagem);
}
function loopInfinito(): never {
while (true) {}
}
Tipo Object
Representa o tipo de qualquer valor que não seja primitivo (não é number, string, boolean, symbol, null ou undefined).
let perfil: object = { usuario: 'admin', ativo: true };
Sintaxe Básica
Declaração de Variáveis
A sintaxe inclui anotações de tipo para garantir a segurança dos tipos.
let contador: number = 0;
const MAX_TENTATIVAS: number = 5;
let emailValido: boolean = false;
Funções
É possível anotar os parâmetros e o valor de retorno.
function multiplicar(a: number, b: number): number {
return a * b;
}
Suporta parâmetros opcionais e padrão.
function criarUsuario(nome: string, papel?: string): object {
return { nome, papel: papel || 'visitante' };
}
function saudacao(nome: string, mensagem: string = 'Olá'): string {
return `${mensagem}, ${nome}!`;
}
Suporta sobrecarga de funções.
function formatar(valor: string): string;
function formatar(valor: number): string;
function formatar(valor: string | number): string {
if (typeof valor === 'string') {
return valor.toUpperCase();
} else {
return valor.toFixed(2);
}
}
Interfaces
Definem a estrutura (a "forma") de um objeto.
interface Produto {
id: number;
nome: string;
preco: number;
descricao?: string;
}
function exibirProduto(produto: Produto): void {
console.log(`${produto.nome} - R$${produto.preco}`);
}
Propriedades podem ser somente leitura e podem incluir assinaturas de índice para propriedades dinâmicas.
interface Configuracao {
readonly caminho: string;
[chave: string]: any;
}
interface FuncaoPesquisa {
(termo: string, pagina: number): boolean;
}
Aliases de Tipo (Type Aliases)
Criam um novo nome para um tipo, usando a palavra-chave type.
type ID = string | number;
type Coordenadas = [number, number];
type Callback = (resultado: boolean) => void;
type Usuario = {
nome: string;
email: string;
};
type Funcionario = Usuario & {
matricula: number;
};
Generics
Permitem a criação de componentes reutilizáveis que funcionam com uma variedade de tipos, em vez de um único tipo específico.
function identidade<T>(argumento: T): T {
return argumento;
}
let saida1 = identidade<string>('texto');
let saida2 = identidade(123); // T inferido como number
Podem ser usados em interfaces e restrições de tipo.
interface Repositorio<T> {
obter(id: number): T;
salvar(item: T): void;
}
interface TemTamanho {
tamanho: number;
}
function exibirTamanho<T extends TemTamanho>(item: T): void {
console.log(item.tamanho);
}
Type Assertions
Permitem indicar ao compilador que você conhece o tipo exato de um valor, útil quando a inferência de tipos não é precisa o suficiente.
let entrada: any = 'isto é uma string';
let tamanhoString: number = (entrada as string).length;
// Sintaxe alternativa (não recomendada em JSX)
let tamanhoString2: number = (<string>entrada).length;