TypeScript: Dominando a Tipagem Estática
Aprenda TypeScript e torne seu código JavaScript mais seguro e robusto
TypeScript: Dominando a Tipagem Estática
TypeScript é um superset tipado de JavaScript que compila para JavaScript puro. Desenvolvido pela Microsoft e lançado em 2012, ele adiciona tipagem estática opcional e recursos avançados de orientação a objetos ao JavaScript, tornando o desenvolvimento de aplicações em larga escala mais seguro e produtivo.
Nota: TypeScript é construído sobre JavaScript. Se você precisa revisar os fundamentos, confira nosso Guia Completo de JavaScript antes de continuar.
Por que TypeScript?
TypeScript oferece benefícios significativos para equipes e projetos de qualquer tamanho:
- Detecção de Erros em Tempo de Compilação - Encontre bugs antes de executar o código
- IntelliSense Aprimorado - Autocompletar inteligente e documentação inline
- Refatoração Segura - Renomeie variáveis e funções com confiança
- Documentação Implícita - Tipos servem como documentação viva
- Escalabilidade - Mantenha projetos grandes organizados e seguros
- Adoção Gradual - Migre de JavaScript incrementalmente
Tipos Básicos
Tipos Primitivos
// Tipos simples
let nome: string = "Maria";
let idade: number = 25;
let ativo: boolean = true;
let nulo: null = null;
let indefinido: undefined = undefined;
// Arrays
let numeros: number[] = [1, 2, 3, 4, 5];
let nomes: Array<string> = ["Ana", "Pedro", "Carlos"];
// Tuplas
let coordenada: [number, number] = [10, 20];
let registro: [string, number, boolean] = ["Maria", 25, true];
// Enum
enum Status {
Pendente = "PENDENTE",
Aprovado = "APROVADO",
Rejeitado = "REJEITADO"
}
let statusPedido: Status = Status.Pendente;
Tipos Avançados
// Union Types
type ID = string | number;
let userId: ID = "abc123";
userId = 42; // Também válido
// Intersection Types
type Pessoa = { nome: string };
type Funcionario = { cargo: string };
type FuncionarioPessoa = Pessoa & Funcionario;
// Literal Types
type Direcao = "norte" | "sul" | "leste" | "oeste";
let direcao: Direcao = "norte";
// Template Literal Types
type EventName = `on${Capitalize<string>}`;
// Nullable Types
let valorOpcional: string | null = null;
valorOpcional = "Valor definido";
Interfaces vs Types
// Interface - ideal para objetos e classes
interface Usuario {
id: number;
nome: string;
email: string;
readonly criadoEm: Date;
endereco?: Endereco; // Propriedade opcional
}
interface Endereco {
rua: string;
cidade: string;
pais: string;
}
// Extensão de interface
interface Admin extends Usuario {
permissoes: string[];
nivel: "junior" | "senior" | "master";
}
// Type alias - mais flexível
type Resultado<T> =
| { sucesso: true; dados: T }
| { sucesso: false; erro: string };
type Callback<T> = (dados: T) => void;
Generics
// Função genérica
function primeiro<T>(array: T[]): T | undefined {
return array[0];
}
const primeiroNumero = primeiro([1, 2, 3]); // number
const primeiraString = primeiro(["a", "b", "c"]); // string
// Classe genérica
class Pilha<T> {
private items: T[] = [];
push(item: T): void {
this.items.push(item);
}
pop(): T | undefined {
return this.items.pop();
}
peek(): T | undefined {
return this.items[this.items.length - 1];
}
}
// Constraints (restrições)
interface ComId {
id: number;
}
function buscarPorId<T extends ComId>(items: T[], id: number): T | undefined {
return items.find(item => item.id === id);
}
// Utility Types
type UsuarioSomenteLeitura = Readonly<Usuario>;
type UsuarioParcial = Partial<Usuario>;
type UsuarioSemEndereco = Omit<Usuario, "endereco">;
type SomenteNomeEmail = Pick<Usuario, "nome" | "email">;
Funções Tipadas
// Função com tipos explícitos
function calcularDesconto(
preco: number,
percentual: number
): number {
return preco * (1 - percentual / 100);
}
// Arrow function tipada
const multiplicar = (a: number, b: number): number => a * b;
// Função com sobrecarga
function processar(valor: string): string;
function processar(valor: number): number;
function processar(valor: string | number): string | number {
if (typeof valor === "string") {
return valor.toUpperCase();
}
return valor * 2;
}
// Type guards
function isString(valor: unknown): valor is string {
return typeof valor === "string";
}
function formatarValor(valor: unknown): string {
if (isString(valor)) {
return valor.trim();
}
return String(valor);
}
Classes com TypeScript
abstract class Entidade {
constructor(
public readonly id: string,
public criadoEm: Date = new Date()
) {}
abstract validar(): boolean;
}
class Produto extends Entidade {
constructor(
id: string,
public nome: string,
public preco: number,
private _estoque: number = 0
) {
super(id);
}
get estoque(): number {
return this._estoque;
}
set estoque(valor: number) {
if (valor < 0) {
throw new Error("Estoque não pode ser negativo");
}
this._estoque = valor;
}
validar(): boolean {
return this.nome.length > 0 && this.preco > 0;
}
aplicarDesconto(percentual: number): number {
return this.preco * (1 - percentual / 100);
}
}
// Implementando interfaces
interface Serializavel {
toJSON(): string;
}
class Item implements Serializavel {
constructor(public nome: string) {}
toJSON(): string {
return JSON.stringify({ nome: this.nome });
}
}
Configuração do Projeto
tsconfig.json Recomendado
{
"compilerOptions": {
"target": "ES2022",
"module": "ESNext",
"moduleResolution": "bundler",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true,
"outDir": "./dist",
"rootDir": "./src",
"declaration": true,
"declarationMap": true,
"sourceMap": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"noImplicitReturns": true,
"noFallthroughCasesInSwitch": true
},
"include": ["src/**/*"],
"exclude": ["node_modules", "dist"]
}
Checklist de Aprendizado
- Dominar tipos primitivos e arrays
- Entender interfaces e type aliases
- Aprender generics e constraints
- Estudar utility types (Partial, Readonly, Pick, Omit)
- Praticar type guards e narrowing
- Configurar projetos com tsconfig.json
- Migrar um projeto JavaScript existente
Erros Comuns a Evitar
Usar→ Useanyem todo lugarunknownou tipos específicosIgnorar erros de compilação→ Corrija todos os erros de tipoNão usar strict mode→ Sempre ativestrict: trueDuplicar tipos→ Use utility types para derivar tipos
Recursos Essenciais
Citação
“TypeScript é JavaScript que escala.” - Anders Hejlsberg, criador do TypeScript
TypeScript transforma a maneira como você escreve JavaScript. Invista tempo aprendendo seus recursos e sua produtividade aumentará significativamente!