TypeScript: Arquivos de declaração do TypeScript

Última atualização: 2026-08-26

Os arquivos de declaração (.d.ts) funcionam como uma ponte entre os mundos do TypeScript e do JavaScript — eles fornecem definições de tipos para o código JavaScript que não possui informações de tipo, permitindo que você utilize com segurança qualquer biblioteca JavaScript em seus projetos TypeScript.

1. O que é um arquivo de declaração?

(1) Problema: a biblioteca JS não possui tipos

TYPESCRIPT
// Usage lodash —— A pure JavaScript library
import _ from "lodash";

// ❌ TypeScript Error: Module not found "lodash" Statement Document
let result = _.chunk([1, 2, 3, 4], 2);

(2) Solução: O arquivo de declaração fornece informações sobre os tipos

Os arquivos de declaração têm a extensão .d.ts e contêm apenas declarações de tipos; eles não incluem código de implementação:

TYPESCRIPT
// lodash.d.ts —— Statement(Describe only the type,No implementation provided)
declare module "lodash" {
  export function chunk<T>(array: T[], size: number): T[][];
  export function debounce(func: Function, wait: number): Function;
  // ... Additional Statements
}

Com o arquivo de declaração, o TypeScript consegue interpretar a API do lodash e fornecer verificação de tipos e sugestões de código.

(3) Três fontes de documentos de declaração

Fonte Descrição Exemplo
Declarações embutidas Incluídas no TypeScript (DOM, ES2020, etc.) lib.dom.d.ts
Incluído no pacote O autor da biblioteca incluiu .d.ts axios/index.d.ts
DefinitelyTyped Declarações de terceiros mantidas pela comunidade @types/lodash


2. Instalando e utilizando o pacote @types

(1) Consultar declarações de tipos

BASH
# Check if a package has @types Statement
npm info @types/lodash

# Installation Type Declaration
npm install @types/lodash --save-dev

(2) O resultado após a instalação

TYPESCRIPT
// After installing @types/lodash — full type support
import _ from "lodash";

let chunks: number[][] = _.chunk([1, 2, 3, 4], 2);  // ✅ Type Safety
let debounced = _.debounce(() => {}, 300);            // ✅ Auto-Complete

(3) Pacotes @types comuns

Nome do pacote Biblioteca correspondente
@types/node Node.js
@types/lodash Lodash
@types/express Express
@types/jest É
@types/react React
@types/jquery jQuery

(4) Detecção automática de declarações de tipo

O TypeScript procura declarações de tipo na seguinte ordem:

  1. index.d.ts no pacote (um tipo embutido)
  2. Declaração sob o código node_modules/@types/
  3. Os locais especificados em tsconfig.json, typeRoots e types


3. Escreva seu próprio arquivo de declaração

(1) Declaração de variáveis globais

Ao importar uma biblioteca JavaScript usando a tag script, é necessário declarar variáveis globais:

TYPESCRIPT
// globals.d.ts
declare var jQuery: (selector: string) => HTMLElement;
declare var $: typeof jQuery;

// Usage
let el = $(".container");  // ✅ Type Safety

(2) Declarações de funções globais

TYPESCRIPT
// globals.d.ts
declare function ga(command: string, ...args: any[]): void;
declare function gtag(type: string, eventName: string, params?: Record<string, any>): void;

// Usage
ga("send", "pageview");               // ✅
gtag("event", "click", { value: 1 });  // ✅

(3) Declaração do módulo

Ao usar pacotes npm sem tipo, declare o módulo da seguinte forma:

TYPESCRIPT
// declarations.d.ts
declare module "untyped-lib" {
  export function doSomething(value: string): number;
  export const version: string;
  export default class Client {
    constructor(options: { host: string; port: number });
    connect(): Promise<void>;
  }
}

// Usage
import Client, { doSomething, version } from "untyped-lib";

(4) Extensões de módulos — Adicionando tipos a módulos existentes

TYPESCRIPT
// Extensions express Module
declare module "express" {
  interface Request {
    user?: {
      id: number;
      name: string;
    };
  }
}

// It is now available at express.Request Safety Guidelines user Properties
import { Request } from "express";
function handler(req: Request) {
  if (req.user) {
    console.log(req.user.name);  // ✅ Type Safety
  }
}

▶ Exemplo: Como escrever uma declaração para uma ferramenta personalizada em JavaScript

TYPESCRIPT
// Suppose there is a legacy-utils.js The file has no type
// legacy-utils.d.ts —— Write a statement for it

declare module "legacy-utils" {
  /**
   * Format the date according to the specified pattern
   * @param date - Date object or timestamp
   * @param pattern - Format patterns, e.g. "YYYY-MM-DD"
   */
  export function formatDate(date: Date | number, pattern: string): string;

  /**
   * Deep-copy objects
   */
  export function deepClone<T>(obj: T): T;

  /**
   * Image Stabilization Function
   */
  export function debounce<T extends (...args: any[]) => any>(
    fn: T,
    delay: number
  ): (...args: Parameters<T>) => void;

  /**
   * Default Export:Toolset Object
   */
  const utils: {
    formatDate: typeof formatDate;
    deepClone: typeof deepClone;
    debounce: typeof debounce;
  };

  export default utils;
}

// Usage——Full Type Support
import utils from "legacy-utils";

let dateStr = utils.formatDate(new Date(), "YYYY-MM-DD");
let cloned = utils.deepClone({ name: "Charlie" });
let debounced = utils.debounce((x: number) => console.log(x), 300);
▶ Experimente

Saída:

TEXT 📖 Somente leitura
// Executed successfully


4. Regras para a criação de arquivos de declaração

(1) Regras básicas

(2) Três tipos de escopo de declaração

TYPESCRIPT
// ── Global Declarations(None import/export) ──
// All declarations in the file are automatically visible throughout the entire project.
declare var GLOBAL_CONFIG: { api: string };
declare function globalHelper(): void;

// ── Module Declaration ──
declare module "my-lib" {
  export function helper(): void;
}

// ── File Module Declaration ──
// At the top of the document, there is import/export → The entire file is a module
import { User } from "./types";
export declare function processUser(user: User): void;

(3) Diretrizes para a exportação de fontes

TYPESCRIPT
// ✅ Recommendations——Export Interfaces and Types
export interface User {
  id: number;
  name: string;
}

export type UserId = number;

// ✅ Recommendations——Exported Function Signatures
export declare function getUser(id: number): User;

// ❌ Not recommended——Export the specific implementation(.d.ts Should not be implemented)
// export function getUser(id: number): User { return ...; }


5. Configuração de tipos no tsconfig

(1) typeRoots — Especifica o diretório para as declarações de tipos

JSON
{
  "compilerOptions": {
    "typeRoots": [
      "./node_modules/@types",
      "./src/types"
    ]
  }
}

(2) tipos — Especifique os pacotes de tipos a serem incluídos

JSON
{
  "compilerOptions": {
    "types": ["node", "jest", "lodash"]
    // Includes only these three @types packages, ignoring the rest
  }
}

(3) Três opções de rigor

JSON
{
  "compilerOptions": {
    "noImplicitAny": true,          // Implicit is prohibited any
    "strict": true,                  // Enable all strict checks
    "skipLibCheck": true             // Skip .d.ts File Type Validation(Speed up compilation)
  }
}


▶ Exemplo: Declarando tipos globais em um arquivo .d.ts

Saída:

TEXT 📖 Somente leitura
10
30
TYPESCRIPT
// env.d.ts — declare global constants and types
declare var APP_VERSION: string;
declare var API_BASE_URL: string;

interface AppWindow extends Window {
  appConfig: {
    theme: "light" | "dark";
    locale: string;
  };
}

// Usage in any .ts file
console.log(`v${APP_VERSION}`);
console.log(APP_VERSION);

Saída:

TEXT 📖 Somente leitura
10
30

▶ Exemplo: Aumentando tipos nativos com declaração de módulo

Saída:

TEXT 📖 Somente leitura
10
30
TYPESCRIPT
// array-ext.d.ts — add a method to the built-in Array type
interface Array<T> {
  last(): T | undefined;
  first(): T | undefined;
}

// Now every array has .last() and .first() with full type safety
let items = [10, 20, 30];
let first = items.first();   // number | undefined
let last = items.last();     // number | undefined

console.log(first);  // 10
console.log(last);   // 30

Saída:

TEXT 📖 Somente leitura
10
30

❓ Perguntas Frequentes

P: Quando é necessário escrever um arquivo de declaração? R: Existem três casos: (1) A biblioteca JavaScript que você está usando não possui um pacote @types; (2) Variáveis globais importadas por meio de uma tag script; (3) Você precisa adicionar propriedades personalizadas a um módulo existente. Na maioria dos casos, basta instalar o @types; escrever seu próprio arquivo de declaração é uma prática relativamente rara.

P: Qual é a diferença entre declare module e declare global? R: declare module "xxx" declara o tipo de um módulo externo — usado para fornecer tipos para pacotes do npm. declare global Adiciona uma declaração ao namespace global dentro de um arquivo de módulo — usado para estender tipos globais (como Window). Os dois têm escopos diferentes: module é no nível do módulo, enquanto global é no nível global.

P: O que tem precedência — o pacote @types ou os tipos embutidos da biblioteca? R: Os tipos embutidos da biblioteca têm precedência. Bibliotecas modernas (como axios e zod) já incluem index.d.ts no pacote, portanto, não há necessidade de instalar o @types separadamente. Você só precisa do @types quando a biblioteca não inclui seus próprios tipos. Se ambos estiverem presentes, o TypeScript dará prioridade às declarações incluídas no pacote.

P: O skipLibCheck deve ser ativado? R: Recomendamos ativá-lo. O skipLibCheck ignora a verificação de tipos para todos os arquivos .d.ts, o que pode acelerar significativamente a compilação (especialmente em projetos grandes). A desvantagem é que ele pode deixar passar erros em declarações de tipos de terceiros — mas esse risco é mínimo, pois o pacote @types é revisado pela comunidade. Os benefícios de desempenho superam amplamente os riscos.

📖 Resumo

📝 Exercícios

  1. Problema básico (Dificuldade ⭐): Escreva um arquivo de declaração para uma biblioteca hipotética de JavaScript chamada math-helpers que inclua add(a, b), subtract(a, b) e a constante PI.
  2. Problema avançado (Dificuldade ⭐⭐): Escreva um arquivo de declaração que estenda a interface String e adicione o método reverse(): string. Pense nisso: por que a extensão de um tipo embutido precisa ser colocada no arquivo .d.ts?
  3. Desafio (Dificuldade: ⭐⭐⭐): Escreva um arquivo de declaração completo para um SDK JavaScript legado sem tipos — incluindo um namespace SDK, uma classe SDK.Client (construtor + métodos), uma enumeração SDK.EventType e uma função global SDK.init(options).
Web-Tutorial.com

Equipe Técnica Web-Tutorial

Uma plataforma de tutoriais mantida por diversos desenvolvedores. Cada tutorial é escrito e revisado por profissionais da área correspondente. Trabalhamos para manter nosso conteúdo preciso e confiável — se encontrar algum problema, avise-nos.

100%