Skip to main content

Types

TypeScript type definitions for postal-mime.

Importing Types

import PostalMime, { addressParser, decodeWords } from 'postal-mime';
import type {
Email,
Address,
Mailbox,
Header,
Attachment,
PostalMimeOptions,
AddressParserOptions,
RawEmail
} from 'postal-mime';

RawEmail

Input types accepted by PostalMime.parse():

type RawEmail =
| string
| ArrayBuffer
| Uint8Array
| Blob
| Buffer
| ReadableStream;

PostalMimeOptions

Configuration options for parsing:

type PostalMimeOptions = {
rfc822Attachments?: boolean;
forceRfc822Attachments?: boolean;
attachmentEncoding?: 'base64' | 'utf8' | 'arraybuffer';
maxNestingDepth?: number;
maxHeadersSize?: number;
};

Properties

PropertyTypeDefaultDescription
rfc822AttachmentsbooleanfalseTreat message/rfc822 without Content-Disposition as attachments
forceRfc822AttachmentsbooleanfalseTreat all message/rfc822 as attachments
attachmentEncodingstring'arraybuffer'Attachment content encoding
maxNestingDepthnumber256Maximum MIME nesting depth
maxHeadersSizenumber2097152Maximum header size (bytes)

Individual email header:

type Header = {
key: string; // Lowercase header name
originalKey: string; // Original header name case
value: string; // Header value
};

Example

const contentType = email.headers.find(
(h: Header) => h.key === 'content-type'
);

Address

Union type for email addresses (can be individual or group):

type Address = Mailbox | {
name: string;
address?: undefined;
group: Mailbox[];
};

Mailbox

Individual email address:

type Mailbox = {
name: string; // Display name (empty string if none)
address: string; // Email address
group?: undefined; // Explicitly undefined (for type narrowing)
};

Type Guard Example

function isMailbox(addr: Address): addr is Mailbox {
return !('group' in addr) || addr.group === undefined;
}

// Usage
if (email.from && isMailbox(email.from)) {
console.log(email.from.address); // TypeScript knows this is Mailbox
}

Attachment

Email attachment:

type Attachment = {
filename: string | null;
mimeType: string;
disposition: 'attachment' | 'inline' | null;
related?: boolean;
description?: string;
contentId?: string;
method?: string;
content: ArrayBuffer | Uint8Array | string;
encoding?: 'base64' | 'utf8';
};

Properties

PropertyTypeDescription
filenamestring | nullOriginal filename
mimeTypestringMIME type
dispositionstring | null'attachment', 'inline', or null
relatedbooleantrue if inline image for HTML
descriptionstringContent-Description header
contentIdstringContent-ID (for inline references)
methodstringCalendar method (for text/calendar)
contentArrayBuffer | stringFile content
encodingstring'base64' or 'utf8' if converted

Email

Complete parsed email:

type Email = {
headers: Header[];
from?: Address;
sender?: Address;
replyTo?: Address[];
deliveredTo?: string;
returnPath?: string;
to?: Address[];
cc?: Address[];
bcc?: Address[];
subject?: string;
messageId?: string;
inReplyTo?: string;
references?: string;
date?: string;
html?: string;
text?: string;
attachments: Attachment[];
};

Property Details

PropertyTypeDescription
headersHeader[]All email headers
fromAddressFrom address
senderAddressSender address
replyToAddress[]Reply-To addresses
deliveredTostringDelivered-To address
returnPathstringReturn-Path address
toAddress[]To addresses
ccAddress[]CC addresses
bccAddress[]BCC addresses
subjectstringSubject line (decoded)
messageIdstringMessage-ID
inReplyTostringIn-Reply-To
referencesstringReferences
datestringDate (ISO 8601)
htmlstringHTML content
textstringPlain text content
attachmentsAttachment[]Attachments

AddressParserOptions

Options for addressParser():

type AddressParserOptions = {
flatten?: boolean;
};

Complete Example

import PostalMime from 'postal-mime';
import type {
Email,
Address,
Mailbox,
Attachment,
PostalMimeOptions
} from 'postal-mime';

// Type guard for mailbox
function isMailbox(addr: Address): addr is Mailbox {
return addr.group === undefined;
}

// Parse with options
const options: PostalMimeOptions = {
attachmentEncoding: 'base64',
maxNestingDepth: 50
};

async function processEmail(rawEmail: string): Promise<void> {
const email: Email = await PostalMime.parse(rawEmail, options);

// Access from address
if (email.from) {
if (isMailbox(email.from)) {
console.log(`From: ${email.from.address}`);
} else {
console.log(`From group: ${email.from.name}`);
}
}

// Access recipients
email.to?.forEach((recipient: Address) => {
if (isMailbox(recipient)) {
console.log(`To: ${recipient.address}`);
}
});

// Access subject
const subject: string | undefined = email.subject;

// Access attachments
email.attachments.forEach((att: Attachment) => {
console.log(`Attachment: ${att.filename}`);

if (att.encoding === 'base64') {
const base64Content: string = att.content as string;
} else {
const binaryContent: ArrayBuffer = att.content as ArrayBuffer;
}
});
}

Using with Cloudflare Workers

import PostalMime from 'postal-mime';
import type { Email } from 'postal-mime';

interface Env {
MY_KV: KVNamespace;
}

export default {
async email(
message: ForwardableEmailMessage,
env: Env,
ctx: ExecutionContext
): Promise<void> {
const email: Email = await PostalMime.parse(message.raw);

// Type-safe access
const subject: string = email.subject ?? '(no subject)';
const fromAddress: string = email.from?.address ?? 'unknown';

await env.MY_KV.put(`email:${Date.now()}`, JSON.stringify({
from: fromAddress,
subject
}));
}
};

Declaration File Location

Types are defined in postal-mime.d.ts at the package root. They are automatically loaded when importing postal-mime in TypeScript projects.

See Also