Skip to content

TypeScript Setup

This guide covers TypeScript configuration for optimal library usage.

{
"compilerOptions": {
"target": "ES2022",
"lib": ["ES2022", "DOM", "DOM.Iterable"],
"module": "ESNext",
"moduleResolution": "bundler",
"strict": true,
"noUncheckedIndexedAccess": true,
"esModuleInterop": true,
"skipLibCheck": true
}
}

ES2024 introduced explicit resource management with using:

using pdfium = await PDFium.init();
// Automatically disposed when scope ends

Option 1: Target ES2022 with lib

{
"compilerOptions": {
"target": "ES2022",
"lib": ["ES2022", "DOM", "DOM.Iterable"]
}
}

Option 2: Target ES2024

{
"compilerOptions": {
"target": "ES2024"
}
}

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();
}

The library is written in strict TypeScript. Enable strict mode:

{
"compilerOptions": {
"strict": true
}
}

This enables:

  • noImplicitAny
  • strictNullChecks
  • strictFunctionTypes
  • strictBindCallApply
  • strictPropertyInitialization
  • noImplicitThis
  • alwaysStrict

The library uses branded types for type-safe handles:

// These are distinct types
type DocumentHandle = number & { readonly __brand: 'DocumentHandle' };
type PageHandle = number & { readonly __brand: 'PageHandle' };
// TypeScript prevents mixing them
function closeDocument(handle: DocumentHandle) { ... }
closeDocument(pageHandle); // Error!
import {
PDFium,
PDFiumDocument,
PDFiumPage,
PDFiumErrorCode,
PageRotation,
AnnotationType,
} from '@scaryterry/pdfium';
import type {
RenderOptions,
RenderResult,
Bookmark,
Annotation,
} from '@scaryterry/pdfium';
import {
PDFium,
PDFiumErrorCode,
type RenderOptions,
type Bookmark,
} from '@scaryterry/pdfium';
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...
}
}
}
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);
}
}
import { AnnotationType } from '@scaryterry/pdfium';
const annotation = page.getAnnotation(0);
if (annotation.type === AnnotationType.Highlight) {
// Process highlight
}
function processPage<T>(
document: PDFiumDocument,
pageIndex: number,
fn: (page: PDFiumPage) => T
): T {
using page = document.getPage(pageIndex);
return fn(page);
}
// Usage
const text = processPage(document, 0, (page) => page.getText());
// text is inferred as string
async function processPageAsync<T>(
document: PDFiumDocument,
pageIndex: number,
fn: (page: PDFiumPage) => Promise<T>
): Promise<T> {
using page = document.getPage(pageIndex);
return await fn(page);
}
{
"compilerOptions": {
"target": "ES2022",
"lib": ["ES2022"],
"module": "NodeNext",
"moduleResolution": "NodeNext",
"strict": true,
"outDir": "./dist",
"rootDir": "./src",
"declaration": true,
"esModuleInterop": true,
"skipLibCheck": true
},
"include": ["src/**/*"]
}
{
"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"]
}
{
"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"]
}