Генерация .d.ts файлов в экосистеме Rollup представляет
собой отдельный слой сборочного процесса, который отвечает за
формирование TypeScript-типов для потребителей библиотеки. В отличие от
основного бандлинга JavaScript-кода, здесь задача заключается не в
объединении модулей, а в точной и консистентной передаче контрактов
типов, которые используются в исходном коде TypeScript или
JSDoc-аннотациях.
Файлы .d.ts являются описанием интерфейсов, функций,
классов и модулей без реализации. Они используются
TypeScript-компилятором для проверки типов в проектах, которые
подключают библиотеку как зависимость.
Ключевая особенность заключается в том, что .d.ts не
исполняются в рантайме, но напрямую влияют на качество интеграции
библиотеки в IDE и системы статической проверки типов.
Основные цели генерации деклараций:
Наиболее прямой способ получения .d.ts файлов —
использование TypeScript Compiler (tsc) в режиме
деклараций.
В tsconfig.json включается:
{
"compilerOptions": {
"declaration": true,
"emitDeclarationOnly": true,
"declarationMap": true,
"outDir": "dist/types"
}
}
Параметры:
declaration: true — включает генерацию
.d.ts;emitDeclarationOnly: true — отключает генерацию
.js;declarationMap: true — создаёт карты соответствий
исходного кода;outDir — отдельная директория для типов.Этот подход прост, но плохо сочетается с Rollup, поскольку Rollup выполняет собственную сборку модулей, и возникает проблема согласования структуры выходных файлов.
Rollup выполняет трансформацию модулей и может:
TypeScript же генерирует .d.ts исходя из файловой
структуры исходного проекта.
Это приводит к рассинхронизации:
.d.ts не совпадают с итоговым
пакетом.Для устранения этой проблемы применяются специализированные плагины Rollup.
Один из базовых способов интеграции TypeScript в Rollup —
использование плагина @rollup/plugin-typescript.
Он позволяет:
.d.ts файлы параллельно с JS;Пример конфигурации:
import typescript from '@rollup/plugin-typescript';
export default {
input: 'src/index.ts',
output: {
dir: 'dist',
format: 'esm'
},
plugins: [
typescript({
declaration: true,
declarationDir: 'dist/types'
})
]
};
Особенности:
В крупных библиотеках этот вариант часто заменяется более специализированными решениями.
Для сложных проектов используется rollup-plugin-dts,
который выполняет отдельную сборку .d.ts файлов.
Его задача — не просто сгенерировать декларации, а объединить их в единый согласованный модульный граф, соответствующий итоговому бандлу JavaScript.
Принцип работы:
.d.ts для каждого модуля;.d.ts файл или набор согласованных
файлов.Пример конфигурации:
import dts from 'rollup-plugin-dts';
export default {
input: 'dist/types/index.d.ts',
output: {
file: 'dist/index.d.ts',
format: 'esm'
},
plugins: [dts()]
};
Преимущество такого подхода заключается в том, что итоговый
.d.ts соответствует структуре JavaScript-бандла.
В зрелых проектах сборка типов отделяется от сборки JavaScript.
Типичная схема:
Rollup собирает Jav * aScript:
src/index.ts → dist/index.jsTypeScript генерирует декларации:
src/index.ts → dist/types/*.d.tsRollup или отдельный шаг объединяет декларации:
dist/types → dist/index.d.tsТакое разделение обеспечивает:
Rollup часто используется для библиотек с несколькими точками входа:
export default {
input: {
main: 'src/index.ts',
utils: 'src/utils.ts'
},
output: {
dir: 'dist',
format: 'esm'
}
};
В этом случае генерация .d.ts усложняется,
поскольку:
rollup-plugin-dts в таких случаях строит общий граф
типов и объединяет их в согласованную структуру, избегая дублирования
экспортов.
Tree-shaking в Rollup удаляет неиспользуемый код на этапе JavaScript-сборки. Однако декларации типов не могут быть оптимизированы столь же агрессивно без потери корректности API.
Типичная проблема:
.d.ts.Это приводит к рассинхронизации публичного API.
Для решения применяются:
index.ts;preserveModules;Опция preserveModules сохраняет структуру исходных
файлов в выходной сборке:
output: {
dir: 'dist',
format: 'esm',
preserveModules: true
}
В этом режиме:
.d.ts становится тривиальнее;Однако увеличивается количество файлов, что может быть нежелательно для публичных библиотек.
declarationMap создаёт сопоставление между
.d.ts и исходными .ts файлами:
{
"compilerOptions": {
"declaration": true,
"declarationMap": true
}
}
Это важно для:
Rollup напрямую не использует declaration maps, но корректная их генерация важна при публикации пакета.
В процессе интеграции Rollup и TypeScript часто возникают системные проблемы.
Причина:
Причина:
export в TypeScript;type-only импортов без поддержки в
сборке.Причина:
.d.ts собираются разными инструментами без
общей конфигурации.На практике используется трёхэтапная схема:
.d.ts;.d.ts.Такой подход обеспечивает:
В некоторых конфигурациях применяется
isolatedDeclarations:
{
"compilerOptions": {
"isolatedDeclarations": true
}
}
Это требует, чтобы каждый файл был самодостаточным с точки зрения типов.
В контексте Rollup это полезно для:
Однако увеличивает строгость требований к архитектуре кода.
Для корректной интеграции типов в npm-пакет используется:
{
"types": "dist/index.d.ts"
}
или:
{
"typings": "dist/index.d.ts"
}
Это связывает entry point JavaScript с декларациями и обеспечивает автоматическое использование типов при установке пакета.
Генерация .d.ts в Rollup-проектах представляет собой
слой синхронизации между двумя системами:
Ключевая инженерная задача заключается не в самой генерации деклараций, а в поддержании идентичности публичного интерфейса между JS- и TS-слоем при изменяющейся структуре модулей и применяемых оптимизациях.