TypeScript Setup
This guide covers TypeScript configuration for optimal library usage.
Recommended Configuration
Section titled “Recommended Configuration”{ "compilerOptions": { "target": "ES2022", "lib": ["ES2022", "DOM", "DOM.Iterable"], "module": "ESNext", "moduleResolution": "bundler", "strict": true, "noUncheckedIndexedAccess": true, "esModuleInterop": true, "skipLibCheck": true }}The using Keyword
Section titled “The using Keyword”ES2024 introduced explicit resource management with using:
using pdfium = await PDFium.init();// Automatically disposed when scope endsEnabling using
Section titled “Enabling using”Option 1: Target ES2022 with lib
{ "compilerOptions": { "target": "ES2022", "lib": ["ES2022", "DOM", "DOM.Iterable"] }}Option 2: Target ES2024
{ "compilerOptions": { "target": "ES2024" }}Without using
Section titled “Without using”If you can’t use using, dispose manually:
const pdfium = await PDFium.init();try { const document = await pdfium.openDocument(data); try { const page = document.getPage(0); try { return page.getText(); } finally { page.dispose(); } } finally { document.dispose(); }} finally { pdfium.dispose();}Strict Mode
Section titled “Strict Mode”The library is written in strict TypeScript. Enable strict mode:
{ "compilerOptions": { "strict": true }}This enables:
noImplicitAnystrictNullChecksstrictFunctionTypesstrictBindCallApplystrictPropertyInitializationnoImplicitThisalwaysStrict
Branded Types
Section titled “Branded Types”The library uses branded types for type-safe handles:
// These are distinct typestype DocumentHandle = number & { readonly __brand: 'DocumentHandle' };type PageHandle = number & { readonly __brand: 'PageHandle' };
// TypeScript prevents mixing themfunction closeDocument(handle: DocumentHandle) { ... }closeDocument(pageHandle); // Error!Import Examples
Section titled “Import Examples”Named Imports
Section titled “Named Imports”import { PDFium, PDFiumDocument, PDFiumPage, PDFiumErrorCode, PageRotation, AnnotationType,} from '@scaryterry/pdfium';Type Imports
Section titled “Type Imports”import type { RenderOptions, RenderResult, Bookmark, Annotation,} from '@scaryterry/pdfium';Combined
Section titled “Combined”import { PDFium, PDFiumErrorCode, type RenderOptions, type Bookmark,} from '@scaryterry/pdfium';Error Handling Types
Section titled “Error Handling Types”import { PDFiumError, DocumentError, PageError, RenderError, PDFiumErrorCode,} from '@scaryterry/pdfium';
try { using document = await pdfium.openDocument(data);} catch (error) { if (error instanceof DocumentError) { // TypeScript knows error.code is PDFiumErrorCode if (error.code === PDFiumErrorCode.DOC_PASSWORD_REQUIRED) { // Handle password... } }}Type Narrowing
Section titled “Type Narrowing”Page Objects
Section titled “Page Objects”import { PageObjectType } from '@scaryterry/pdfium';
for (const obj of page.getObjects()) { if (obj.type === PageObjectType.Text) { // TypeScript knows: obj is TextObject console.log(obj.text, obj.fontSize); } else if (obj.type === PageObjectType.Image) { // TypeScript knows: obj is ImageObject console.log(obj.width, obj.height); }}Annotations
Section titled “Annotations”import { AnnotationType } from '@scaryterry/pdfium';
const annotation = page.getAnnotation(0);if (annotation.type === AnnotationType.Highlight) { // Process highlight}Generic Patterns
Section titled “Generic Patterns”Type-Safe Page Processor
Section titled “Type-Safe Page Processor”function processPage<T>( document: PDFiumDocument, pageIndex: number, fn: (page: PDFiumPage) => T): T { using page = document.getPage(pageIndex); return fn(page);}
// Usageconst text = processPage(document, 0, (page) => page.getText());// text is inferred as stringAsync Page Processor
Section titled “Async Page Processor”async function processPageAsync<T>( document: PDFiumDocument, pageIndex: number, fn: (page: PDFiumPage) => Promise<T>): Promise<T> { using page = document.getPage(pageIndex); return await fn(page);}Configuration Files
Section titled “Configuration Files”Node.js Project
Section titled “Node.js Project”{ "compilerOptions": { "target": "ES2022", "lib": ["ES2022"], "module": "NodeNext", "moduleResolution": "NodeNext", "strict": true, "outDir": "./dist", "rootDir": "./src", "declaration": true, "esModuleInterop": true, "skipLibCheck": true }, "include": ["src/**/*"]}Vite Project
Section titled “Vite Project”{ "compilerOptions": { "target": "ES2022", "lib": ["ES2022", "DOM", "DOM.Iterable"], "module": "ESNext", "moduleResolution": "bundler", "strict": true, "jsx": "react-jsx", "skipLibCheck": true, "allowImportingTsExtensions": true, "noEmit": true }, "include": ["src"]}Next.js Project
Section titled “Next.js Project”{ "compilerOptions": { "target": "ES2022", "lib": ["ES2022", "DOM", "DOM.Iterable"], "module": "ESNext", "moduleResolution": "bundler", "strict": true, "jsx": "preserve", "incremental": true, "plugins": [{ "name": "next" }], "paths": { "@/*": ["./src/*"] } }, "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"], "exclude": ["node_modules"]}See Also
Section titled “See Also”- Installation — Package installation
- Quick Start — Getting started
- Resource Management — Using disposal