ARTICLE AD BOX
I am trying to add a custom static method to the built-in global URL class in TypeScript so that I can do something like:
URL.create("/path", "https://example.com")At runtime this is trivial:
(globalThis.URL as any).create = function ( url: string | URL, base?: string | URL ): URL { return new URL(url, base); };The issue is getting this to work at compile time in a type-safe way. In lib.dom.d.ts, URL is declared like this:
declare var URL: { prototype: URL; new(url: string | URL, base?: string | URL): URL; canParse(url: string | URL, base?: string | URL): boolean; parse(url: string | URL, base?: string | URL): URL | null; createObjectURL(obj: Blob | MediaSource): string; revokeObjectURL(url: string): void; };Notice that this is a:
var URL: { ... }with an anonymous object type, so this prevents declaration merging such as:
declare global { interface URLConstructor { create(url: string | URL, base?: string | URL): URL; } }because there is no URLConstructor in the standard library to merge with. As a result, I can't easily add static methods the same way we typically can with built-ins like Array, whose static side is declared via ArrayConstructor in the standard library and therefore supports declaration merging.
This also fails:
declare global { var URL: typeof URL & { create(url: string | URL, base?: string | URL): URL; }; }since variable declarations don't merge the same way interfaces do.
Is there any type-safe way to augment the static side of the built-in global URL in TypeScript so that:
URL.create(...)is both:
available at runtime; and properly typed at compile time;without introducing a separate alias (like URLEx)?
Or is this fundamentally impossible because the DOM lib defines URL as a var with an anonymous type?
If this is by design, what is the recommended pattern for extending built-in globals with static methods?
