Skip to content

Introduce CookieExpiryDate nominal type #588

Description

@colincasey

Part of #581.

Motivation

RFC 6265 §5.1.1 defines a specific date parsing algorithm with constraints: year ≥ 1601, day 1–31, hour 0–23, minute 0–59, second 0–59. The parseDate() function implements this algorithm and returns a Date, but nothing distinguishes a Date produced by RFC-compliant cookie date parsing from an arbitrary new Date(). This matters because cookie dates have different validity rules than general-purpose dates.

Current usage

function parseDate(cookieDate: Nullable<string>): Date | undefined

class Cookie {
  expires: Date | 'Infinity' | null
  setExpires(exp: string | Date): void
}

Nominal type design

declare const tag: unique symbol;

export type CookieExpiryDate = Date & { readonly [tag]: true };

export namespace CookieExpiryDate {
  /** Parse a cookie date string per RFC 6265 §5.1.1. */
  export function parse(input: string): CookieExpiryDate | undefined {
    // Existing parseDate() logic with RFC constraints
  }

  /** Wrap a known-valid Date (e.g., from Max-Age calculation). */
  export function fromDate(date: Date): CookieExpiryDate {
    return date as CookieExpiryDate;
  }
}

API-compatible refactoring strategy

Return type narrowing (non-breaking)

Function Current return New return Breaking?
parseDate() Date | undefined CookieExpiryDate | undefined No — assignable to Date

Unchanged public surfaces

  • Cookie.expires remains Date | 'Infinity' | null
  • Cookie.setExpires() parameter remains string | Date
  • CreateCookieOptions.expires remains Date | 'Infinity' | null

Internal usage

  • expiryTime() and TTL() can work with CookieExpiryDate internally
  • Distinguishes RFC-parsed dates from arbitrary Date objects in internal logic

Metadata

Metadata

Assignees

No one assigned

    Labels

    6265bisOfficially proposed changes to RFC 6265

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions