惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Google DeepMind News
Google DeepMind News
aimingoo的专栏
aimingoo的专栏
爱范儿
爱范儿
D
Docker
I
InfoQ
Microsoft Security Blog
Microsoft Security Blog
G
Google Developers Blog
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
Vercel News
Vercel News
H
Hackread – Cybersecurity News, Data Breaches, AI and More
T
Tailwind CSS Blog
D
DataBreaches.Net
月光博客
月光博客
N
Netflix TechBlog - Medium
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
V
Visual Studio Blog
MyScale Blog
MyScale Blog
B
Blog
阮一峰的网络日志
阮一峰的网络日志
L
LangChain Blog
Recent Announcements
Recent Announcements
Microsoft Azure Blog
Microsoft Azure Blog
WordPress大学
WordPress大学

DEV Community

Authentication Security Deep Dive: From Brute Force to Salted Hashing (With Java Examples) Why AI Systems Don’t Fail — They Drift Spilling beans for how i learn for exam😁"Reinforcement Learning Cheat Sheet" I Replaced Chrome with Safari for AI Browser Automation. Here's What Broke (and What Finally Worked) How Python Borrows Other People's Work The $40 Architecture: Processing 1 Billion API Requests with 99.99% Uptime Vibe Coding: A Workflow Guide (From Zero to SaaS) Most webhook security guides protect the wrong side. The scary part is delivery. Headless CMS for TanStack Start: Build a Blog with Cosmic EU Age Verification App "Hacked in 2 Minutes" — What Actually Happened Comfy Cloud’s delete function does not actually remove files Running AI Models on GPU Cloud Servers: A Beginner Guide Event-driven media intelligence with AWS Step Functions and Bedrock I scored 500 AI prompts across 8 quality dimensions — here's what broke How to Call Google Gemini API from Next.js (Free Tier, No Backend Needed) The Portal Protocol: Reclaiming Human Connection in the Age of AI How to Fix Your Team's Scattered Knowledge Problem With a Self-Hosted Forum Intro to tc Cloud Functors: A Graph-First Mental Model for the Modern Cloud Designing Multi-Tenant Backends With Both Ownership and Team Access I Built a Neumorphic CSS Library with 77+ Components — Here's What I Learned PostgreSQL Performance Optimization: Why Connection Pooling Is Critical at Scale Cómo construí un SaaS multi-rubro para gestionar expensas en Argentina con FastAPI + Vue 3 🚀 I Built an Ethical Hacking Scanner Tool – Open Source Project I Replaced /usage and /context in Claude Code With a Single Statusline A Pythonic Way to Handle Emails (IMAP/SMTP) with Auto-Discovery and AI-Ready Design I Collected 8.9 Million Polymarket Price Points — Here's What I Found About How Markets Really Move EcoTrack AI — Carbon Footprint Tracker & Dashboard Everyone's Using AI. No One Agrees How. 5 self-hosted ebook managers worth trying in 2026 Building Your First AI Agent with LangChain: From Chatbot to Autonomous Assistant
TypeScript: Interfaces
Yuri Peixinho · 2026-06-14 · via DEV Community

Yuri Peixinho

Introdução

As interfaces são uma das pedras fundamentais do Typescript. Elas descrevem formas que um objeto deve ter — um contrato que qualquer valor implemente aquela interface precisa respeitar.

Types vs Interfaces

Essa é a dúvida mais comum entre desenvolvedores TypeScript. As duas construções parecem fazer a mesma coisa na maioria dos casos, mas têm diferenças importantes.

A regra prática é:

Objetos públicos, contratos de classe  interface
Unions, primitivos, mapped types, composições  type

Ambas descrevem a forma de um objeto:

type Usuario = {
  id: number;
  nome: string;
};

interface Usuario {
  id: number;
  nome: string;
}

Na prática, para objetos simples, são intercambiáveis (trocado, substituído).

Diferença 1 — Declaration Merging

Interfaces podem ser declaradas múltiplas vezes e o TypeScript mescla automaticamente:

interface Configuracao {
  host: string;
}

interface Configuracao {
  porta: number;
}

// TypeScript mescla as duas:
// { host: string; porta: number }
const config: Configuracao = {
  host: "localhost",
  porta: 5432
};

Com type, isso gera erro:

type Configuracao = { host: string };
type Configuracao = { porta: number }; // ❌ identificador duplicado

Declaration merging é especialmente útil para estender libs externas sem modificar o código delas.

Diferença 2 — Tipos compostos

type consegue representar qualquer coisa, interface só representa objetos:

// só type consegue fazer isso:
type ID = string | number;
type Status = "ativo" | "inativo";
type Nullable<T> = T | null;
type Par<T> = [T, T];

Diferença 3 — Extends vs Intersecção

// interface usa extends
interface Animal { nome: string }
interface Cachorro extends Animal { raca: string }

// type usa &
type Animal = { nome: string }
type Cachorro = Animal & { raca: string }

Funcionalmente equivalentes, mas extends em interface gera mensagens de erro mais claras.

Declaração de Interfaces

Interface declaration é a sintaxe formal de declarar uma interface — mas vai além de propriedades simples. Interfaces suportam vários tipos de membros.

Propriedades

interface Produto {
  id: number;           // obrigatória
  descricao?: string;   // opcional
  readonly codigo: string; // somente leitura
}

readonly impede atribuição após a criação do objeto.

Métodos

interface Repositorio<T> {
  buscarPorId(id: string): Promise<T>;
  salvar(entidade: T): Promise<T>;
  deletar(id: string): Promise<void>;
  listar(): Promise<T[]>;
}

Call Signatures

interface Validador {
  (valor: string): boolean;
}

const validarCNPJ: Validador = (cnpj) => cnpj.length === 14;

Implementação em classes

interface Transmissor {
  transmitir(payload: unknown): Promise<Protocolo>;
  consultar(protocolo: string): Promise<Status>;
}

class TransmissorReinf implements Transmissor {
  async transmitir(payload: unknown): Promise<Protocolo> {
    // implementação
  }

  async consultar(protocolo: string): Promise<Status> {
    // implementação
  }
}

Se a classe não implementar algum método da interface, o TypeScript acusa erro em tempo de compilação.

Extendendo interfaces

Interfaces podem ser estendidas para criar hierarquias de contratos sem duplicar código.

Extends simples

interface EntidadeBase {
  id: string;
  criadoEm: Date;
  atualizadoEm: Date;
}

interface Tenant extends EntidadeBase {
  cnpj: string;
  razaoSocial: string;
}

interface Evento extends EntidadeBase {
  tipo: string;
  competencia: string;
}

Extends múltiplo

Uma interface pode estender várias ao mesmo tempo:

interface ComAuditoria {
  criadoPor: string;
  atualizadoPor: string;
}

interface ComSoftDelete {
  deletadoEm?: Date;
  ativo: boolean;
}

interface EntidadeCompleta extends ComAuditoria, ComSoftDelete {
  id: string;
}

// EntidadeCompleta tem tudo:
// id, criadoPor, atualizadoPor, deletadoEm, ativo

Sobrescrevendo propriedades

Você pode sobrescrever uma propriedade herdada, mas o novo tipo precisa ser compatível com o original:

interface Base {
  id: string | number;
}

interface Derivada extends Base {
  id: string; // ✅ string é subconjunto de string | number
}

interface Invalida extends Base {
  id: boolean; // ❌ boolean não é compatível com string | number
}

Caso prático — sistema fiscal

interface EntidadeBase {
  id: string;
  criadoEm: Date;
  atualizadoEm: Date;
  ativo: boolean;
}

interface EventoFiscal extends EntidadeBase {
  tenantId: string;
  competencia: string;
  status: "pendente" | "processando" | "concluido" | "erro";
}

interface EventoEFDReinf extends EventoFiscal {
  codigoEvento: string;
  cnpjContribuinte: string;
}

interface EventoEFinanceira extends EventoFiscal {
  rubrica: string;
  tipoMovimento: string;
}

Tipos Híbridos

Hybrid types são interfaces que descrevem um valor que é simultaneamente uma função e um objeto. Parece incomum, mas existe em várias libs JavaScript.

Hybrid types são raramente necessários em código novo — são mais úteis para tipar libs JavaScript existentes que foram escritas antes do TypeScript existir. Em código novo, prefira separar a função do objeto explicitamente.

Em JavaScript, funções são objetos — então uma função pode ter propriedades:

function contador() { ... }
contador.total = 0;        // função com propriedade
contador.resetar = () => { ... }; // função com método

Interfaces conseguem descrever exatamente isso.

interface Contador {
  (): number;           // call signature — é uma função
  total: number;        // propriedade
  resetar(): void;      // método
}

function criarContador(): Contador {
  let count = 0;

  const contador = function(): number {
    return ++count;
  } as Contador;

  contador.total = 0;
  contador.resetar = () => { count = 0; };

  return contador;
}

const c = criarContador();
c();          // chama como função → 1
c();          // → 2
c.total;      // acessa propriedade
c.resetar();  // chama método