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
// 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:
// 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
# 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
// 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:
index.d.tsno pacote (um tipo embutido)- Declaração sob o código
node_modules/@types/ - Os locais especificados em
tsconfig.json,typeRootsetypes
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:
// 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
// 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:
// 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
// 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
// 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);
Saída:
// Executed successfully
4. Regras para a criação de arquivos de declaração
(1) Regras básicas
.d.tsO arquivo contém apenas declarações; não inclui nenhuma implementação.- Use a palavra-chave
declarepara declarar uma entidade externa exportnão é obrigatório — a menos que apareça na declaração de um módulo- Nível superior
exportTransforma o arquivo em uma declaração de módulo (em vez de uma declaração global)
(2) Três tipos de escopo de declaração
// ── 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
// ✅ 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
{
"compilerOptions": {
"typeRoots": [
"./node_modules/@types",
"./src/types"
]
}
}
(2) tipos — Especifique os pacotes de tipos a serem incluídos
{
"compilerOptions": {
"types": ["node", "jest", "lodash"]
// Includes only these three @types packages, ignoring the rest
}
}
(3) Três opções de rigor
{
"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:
10
30
// 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:
10
30
▶ Exemplo: Aumentando tipos nativos com declaração de módulo
Saída:
10
30
// 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:
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 moduleedeclare global? R:declare module "xxx"declara o tipo de um módulo externo — usado para fornecer tipos para pacotes do npm.declare globalAdiciona uma declaração ao namespace global dentro de um arquivo de módulo — usado para estender tipos globais (comoWindow). Os dois têm escopos diferentes:moduleé no nível do módulo, enquantoglobalé 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.tsno 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
- O arquivo de declaração
.d.tsfornece informações de tipo para o código JavaScript — ele contém apenas declarações, sem implementação - Três fontes de declarações de tipos: as integradas ao TypeScript, as fornecidas por bibliotecas e os pacotes da comunidade @types
- Instalar declarações de tipos de terceiros usando
npm install @types/package-name - Situações em que você cria seus próprios arquivos de declaração: bibliotecas JavaScript sem tipos, variáveis globais e extensões de módulos
declareDeclara uma entidade externa usando uma palavra-chave;declare moduleDeclara um tipo de módulo- A configuração
typeRoots/types/noImplicitAny/skipLibCheckemtsconfigcontrola a resolução de tipos e o nível de rigor
📝 Exercícios
- Problema básico (Dificuldade ⭐): Escreva um arquivo de declaração para uma biblioteca hipotética de JavaScript chamada
math-helpersque incluaadd(a, b),subtract(a, b)e a constantePI. - Problema avançado (Dificuldade ⭐⭐): Escreva um arquivo de declaração que estenda a interface
Stringe adicione o métodoreverse(): string. Pense nisso: por que a extensão de um tipo embutido precisa ser colocada no arquivo.d.ts? - Desafio (Dificuldade: ⭐⭐⭐): Escreva um arquivo de declaração completo para um SDK JavaScript legado sem tipos — incluindo um namespace
SDK, uma classeSDK.Client(construtor + métodos), uma enumeraçãoSDK.EventTypee uma função globalSDK.init(options).