🌐 Detecting your location…
📢 Advertisement — Configure AdSense in Appearance → Customize → AdSense Settings

Guia completo do TypeScript 2026: tipos, genéricos e padrões de produção

⏱️6 min read  ·  1,312 words

TypeScript se tornou o padrão para o desenvolvimento moderno de JavaScript. Em 2026, mais de 80% dos novos projetos JavaScript usam TypeScript. Este guia completo cobre tudo, desde tipos básicos até genéricos avançados, decoradores e padrões de produção.

Por que TypeScript em 2026?

A natureza dinâmica do JavaScript causa erros de tempo de execução que o TypeScript detecta em tempo de compilação. Os benefícios são claros:

  • Detecte bugs cedo— erros de tipo em tempo de compilação, não em produção
  • Melhores ferramentas— preenchimento automático, refatoração e navegação no VS Code
  • Código autodocumentado— tipos servem como documentação inline
  • Confiança em grande escala— refatoração segura em milhares de arquivos

Instalação e configuração

Instale o TypeScript globalmente ou como uma dependência de desenvolvimento:

# Install TypeScript
npm install -g typescript

# Or as dev dependency
npm install --save-dev typescript

# Check version
tsc --version

# Initialize tsconfig
tsc --init

Práticas recomendadas de tsconfig.json

Pronto para produçãotsconfig.jsonpara 2026:

{
  "compilerOptions": {
    "target": "ES2022",
    "module": "ESNext",
    "moduleResolution": "bundler",
    "strict": true,
    "noUncheckedIndexedAccess": true,
    "exactOptionalPropertyTypes": true,
    "noImplicitOverride": true,
    "lib": ["ES2022", "DOM"],
    "outDir": "./dist",
    "rootDir": "./src",
    "declaration": true,
    "sourceMap": true,
    "esModuleInterop": true,
    "skipLibCheck": true
  },
  "include": ["src/**/*"],
  "exclude": ["node_modules", "dist"]
}

Tipos Básicos

O sistema de tipos do TypeScript começa com primitivos e aumenta:

// Primitives
const name: string = "Alice";
const age: number = 30;
const active: boolean = true;
const nothing: null = null;
const unknown: undefined = undefined;

// Arrays
const scores: number[] = [95, 87, 92];
const tags: Array<string> = ["ts", "js", "node"];

// Tuples (fixed-length arrays with known types)
const point: [number, number] = [10, 20];
const entry: [string, number] = ["age", 30];

// Union types
let id: string | number = "user_123";
id = 456; // also valid

// Literal types
type Direction = "north" | "south" | "east" | "west";
const dir: Direction = "north";

// any, unknown, never
const userInput: unknown = getUserInput();
if (typeof userInput === "string") {
  console.log(userInput.toUpperCase()); // type narrowed to string
}

Interfaces versus tipos

Ambos definem formas de objetos, mas com diferenças importantes:

// Interface — can be merged (declaration merging)
interface User {
  id: number;
  name: string;
  email?: string; // optional
}

// Extend interface
interface AdminUser extends User {
  role: "admin" | "superadmin";
  permissions: string[];
}

// Type alias — more flexible, supports unions and intersections
type ApiResponse<T> = {
  data: T;
  error: string | null;
  status: number;
};

// Intersection type
type AuthUser = User & { token: string };

// Prefer interface for object shapes, type for unions/intersections
const user: AdminUser = {
  id: 1,
  name: "Alice",
  role: "admin",
  permissions: ["read", "write"]
};

Genéricos

Os genéricos tornam o código reutilizável e ao mesmo tempo mantêm a segurança do tipo:

// Generic function
function first<T>(arr: T[]): T | undefined {
  return arr[0];
}

const num = first([1, 2, 3]); // type: number | undefined
const str = first(["a", "b"]); // type: string | undefined

// Generic with constraints
function getProperty<T, K extends keyof T>(obj: T, key: K): T[K] {
  return obj[key];
}

const user = { id: 1, name: "Alice", age: 30 };
const name = getProperty(user, "name"); // type: string
const id = getProperty(user, "id");     // type: number

// Generic interface
interface Repository<T> {
  findById(id: number): Promise<T | null>;
  findAll(): Promise<T[]>;
  create(item: Omit<T, "id">): Promise<T>;
  update(id: number, item: Partial<T>): Promise<T>;
  delete(id: number): Promise<void>;
}

// Generic class
class Stack<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]; }
  isEmpty(): boolean { return this.items.length === 0; }
}

const stack = new Stack<number>();
stack.push(1);
stack.push(2);
console.log(stack.pop()); // 2

Tipos de utilitários

O TypeScript vem com poderosos tipos de utilitários integrados:

interface Product {
  id: number;
  name: string;
  price: number;
  description: string;
  inStock: boolean;
}

// Partial — all fields optional
type ProductDraft = Partial<Product>;

// Required — all fields required
type FullProduct = Required<Product>;

// Pick — select specific fields
type ProductSummary = Pick<Product, "id" | "name" | "price">;

// Omit — exclude fields
type NewProduct = Omit<Product, "id">;

// Readonly — prevent mutation
type ImmutableProduct = Readonly<Product>;

// Record — map type
type CategoryMap = Record<string, Product[]>;

// ReturnType — extract function return type
async function fetchUser() {
  return { id: 1, name: "Alice", email: "alice@example.com" };
}
type User = Awaited<ReturnType<typeof fetchUser>>;

// Parameters — extract function parameters
function createOrder(userId: number, items: string[], total: number) {}
type OrderParams = Parameters<typeof createOrder>;

Padrões Avançados: Tipos Condicionais

// Conditional type
type IsArray<T> = T extends any[] ? true : false;

type A = IsArray<string[]>; // true
type B = IsArray<string>;   // false

// Infer keyword
type UnpackArray<T> = T extends (infer U)[] ? U : T;
type Unpacked = UnpackArray<string[]>; // string
type NotArray = UnpackArray<number>;   // number

// Mapped types
type Optional<T> = {
  [K in keyof T]?: T[K];
};

// Template literal types (TypeScript 4.1+)
type EventName<T extends string> = `on${Capitalize<T>}`;
type ClickEvent = EventName<"click">; // "onClick"
type FocusEvent = EventName<"focus">; // "onFocus"

// Discriminated unions
type Result<T> =
  | { success: true; data: T }
  | { success: false; error: string };

function processResult<T>(result: Result<T>): T {
  if (result.success) {
    return result.data; // TypeScript knows this is T
  }
  throw new Error(result.error); // TypeScript knows error is string
}

TypeScript com React

import React, { useState, useCallback, FC } from "react";

interface ButtonProps {
  label: string;
  onClick: () => void;
  variant?: "primary" | "secondary" | "danger";
  disabled?: boolean;
  children?: React.ReactNode;
}

const Button: FC<ButtonProps> = ({
  label,
  onClick,
  variant = "primary",
  disabled = false,
  children
}) => {
  return (
    <button
      className={`btn btn-${variant}`}
      onClick={onClick}
      disabled={disabled}
    >
      {children ?? label}
    </button>
  );
};

// Generic component
interface ListProps<T> {
  items: T[];
  renderItem: (item: T, index: number) => React.ReactNode;
  keyExtractor: (item: T) => string | number;
}

function List<T>({ items, renderItem, keyExtractor }: ListProps<T>) {
  return (
    <ul>
      {items.map((item, index) => (
        <li key={keyExtractor(item)}>{renderItem(item, index)}</li>
      ))}
    </ul>
  );
}

// Custom hook with types
function useLocalStorage<T>(key: string, initialValue: T) {
  const [value, setValue] = useState<T>(() => {
    const stored = localStorage.getItem(key);
    return stored ? JSON.parse(stored) : initialValue;
  });

  const setStoredValue = useCallback((newValue: T) => {
    setValue(newValue);
    localStorage.setItem(key, JSON.stringify(newValue));
  }, [key]);

  return [value, setStoredValue] as const;
}

Decoradores TypeScript (2026)

TypeScript 5.0+ suporta decoradores de Estágio 3:

// Class decorator
function singleton<T extends { new(...args: any[]): {} }>(constructor: T) {
  let instance: T;
  return class extends constructor {
    constructor(...args: any[]) {
      if (instance) return instance;
      super(...args);
      instance = this as any;
    }
  };
}

// Method decorator — log execution time
function measure(_target: any, key: string, descriptor: PropertyDescriptor) {
  const original = descriptor.value;
  descriptor.value = async function (...args: any[]) {
    const start = performance.now();
    const result = await original.apply(this, args);
    const duration = performance.now() - start;
    console.log(`${key} took ${duration.toFixed(2)}ms`);
    return result;
  };
  return descriptor;
}

class UserService {
  @measure
  async fetchUsers(): Promise<User[]> {
    const r = await fetch("/api/users");
    return r.json();
  }
}

Lista de verificação do modo estrito

Habilite estas opções do compilador para máxima segurança de tipo:

  • strict: true— permite todas as verificações rigorosas
  • noUncheckedIndexedAccess: true– retornos de acesso ao arrayT | undefined
  • exactOptionalPropertyTypes: trueundefinednão atribuível a opcional
  • noImplicitOverride: true– deve usaroverridepalavra-chave
  • noPropertyAccessFromIndexSignature: true– use notação de colchetes para assinaturas de índice

Ferramentas TypeScript em 2026

  • Bioma– linter + formatador mais rápido, nativo de TypeScript
  • tsx— execute arquivos TypeScript diretamente sem compilar
  • tsup— empacotador zero-config para bibliotecas TypeScript
  • Teste— Primeiros testes de TypeScript com ESM nativo
  • tRPC— segurança de ponta a ponta para aplicativos full-stack

Principais conclusões

TypeScript em 2026 é maduro, rápido e essencial para o desenvolvimento profissional de JavaScript. Comece comstrict: true, use interfaces para formatos de objetos, apoie-se em tipos de utilitários e aproveite genéricos para código reutilizável. O ecossistema de ferramentas nunca foi melhor.

✍️ Leave a Comment

Your email address will not be published. Required fields are marked *

🌐 Read in:🇬🇧 English🇩🇪 Deutsch🇧🇷 Português🇸🇦 العربية🇮🇳 हिन्दी🇧🇩 বাংলা