Unified — это экосистема инструментов для работы с синтаксическими деревьями (AST) текста, которая включает библиотеки Remark для Markdown и Rehype для HTML. Для полноценной работы с этими библиотеками в TypeScript важно правильно настроить типизацию, конфигурацию проекта и поддержку плагинов.
Для работы с unified, Remark и Rehype в проекте TypeScript необходимо установить основные пакеты и их типы:
npm install unified remark remark-parse remark-stringify rehype rehype-parse rehype-stringify
npm install -D typescript @types/node
Если используются плагины, важно также установить соответствующие типы, если они доступны:
npm install remark-gfm rehype-highlight
npm install -D @types/remark-gfm @types/rehype-highlight
TypeScript требует корректной настройки tsconfig.json
для работы с модулями ES и import/export:
{
"compilerOptions": {
"target": "ES2020",
"module": "ESNext",
"moduleResolution": "Node",
"strict": true,
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"skipLibCheck": true,
"resolveJsonModule": true,
"allowSyntheticDefaultImports": true,
"declaration": true,
"outDir": "./dist"
},
"include": ["src"]
}
Ключевые параметры:
esModuleInterop и
allowSyntheticDefaultImports — обеспечивают корректный
импорт CommonJS-пакетов, к которым относятся некоторые плагины
unified.skipLibCheck — предотвращает ошибки типизации при
несовершенной типизации плагинов.strict — включает строгую проверку типов, что критично
для сложных цепочек плагинов.Unified использует цепочки плагинов через метод use. В
TypeScript важно типизировать плагины, чтобы избежать ошибок при
передаче параметров.
Пример цепочки плагинов для Markdown → HTML:
import { unified } from 'unified';
import remarkParse from 'remark-parse';
import remarkGfm from 'remark-gfm';
import remarkRehype from 'remark-rehype';
import rehypeStringify from 'rehype-stringify';
const processor = unified()
.use(remarkParse) // Парсинг Markdown
.use(remarkGfm) // Расширения GitHub Flavored Markdown
.use(remarkRehype) // Конвертация в HTML AST
.use(rehypeStringify); // Генерация HTML
async function parseMarkdown(md: string): Promise<string> {
const file = await processor.process(md);
return String(file);
}
Здесь важно учитывать:
process возвращает объект типа VFile,
который нужно преобразовать в строку.import, а не require, иначе могут возникнуть
проблемы с типами.Unified использует unist (Universal Syntax Tree) для представления дерева документа. Типизация AST позволяет безопасно обращаться к узлам дерева:
import { Root, Content } from 'mdast';
function getHeadings(tree: Root): string[] {
return tree.children
.filter((node): node is { type: 'heading', depth: number, children: Content[] } => node.type === 'heading')
.map(node => node.children.map(child => 'value' in child ? child.value : '').join(''));
}
Особенности:
Root и Content импортируются из
mdast для Markdown и hast для HTML.Поскольку многие плагины Remark/Rehype пишутся на CommonJS, а
TypeScript с ESM использует синтаксис import, часто
возникает необходимость комбинировать импорты:
import remarkGfm from 'remark-gfm';
// vs
// const remarkGfm = require('remark-gfm');
Использование esModuleInterop: true позволяет обращаться
к плагинам как к default-экспорту, что упрощает типизацию и
предотвращает ошибки.
Если создается собственный плагин, его типизация оформляется следующим образом:
import { Plugin } from 'unified';
import { Root } from 'mdast';
const myRemarkPlugin: Plugin<[string?], Root> = (options = {}) => {
return (tree, file) => {
// манипуляции с tree
};
};
Параметры:
[string?] — тип опций плагина (необязательный).Root — тип дерева Markdown.file имеет тип VFile, автоматически
типизированный unified.Для полноценного TypeScript-проекта рекомендуется подключить:
eslint-plugin-unicorn и eslint-plugin-mdx для
проверок AST.typeRoots и paths в
tsconfig.json для корректного поиска типов плагинов.import при
esModuleInterop: true.mdast и
hast) вместо any.Plugin<Options, Tree>.process,
run и runSync.skipLibCheck: true для совместимости с
несовершенно типизированными сторонними плагинами.Эта конфигурация позволяет TypeScript корректно работать с unified, Remark и Rehype, обеспечивая строгую проверку типов, поддержку современных модулей и удобную интеграцию с пользовательскими и сторонними плагинами.