diff --git a/packages/bun-types/globals.d.ts b/packages/bun-types/globals.d.ts index 6ce65ab7495e..6b74d1085b3a 100644 --- a/packages/bun-types/globals.d.ts +++ b/packages/bun-types/globals.d.ts @@ -943,35 +943,43 @@ interface DOMException extends Error { readonly INVALID_NODE_TYPE_ERR: 24; readonly DATA_CLONE_ERR: 25; } -declare var DOMException: { - prototype: DOMException; - new (message?: string, name?: string): DOMException; - readonly INDEX_SIZE_ERR: 1; - readonly DOMSTRING_SIZE_ERR: 2; - readonly HIERARCHY_REQUEST_ERR: 3; - readonly WRONG_DOCUMENT_ERR: 4; - readonly INVALID_CHARACTER_ERR: 5; - readonly NO_DATA_ALLOWED_ERR: 6; - readonly NO_MODIFICATION_ALLOWED_ERR: 7; - readonly NOT_FOUND_ERR: 8; - readonly NOT_SUPPORTED_ERR: 9; - readonly INUSE_ATTRIBUTE_ERR: 10; - readonly INVALID_STATE_ERR: 11; - readonly SYNTAX_ERR: 12; - readonly INVALID_MODIFICATION_ERR: 13; - readonly NAMESPACE_ERR: 14; - readonly INVALID_ACCESS_ERR: 15; - readonly VALIDATION_ERR: 16; - readonly TYPE_MISMATCH_ERR: 17; - readonly SECURITY_ERR: 18; - readonly NETWORK_ERR: 19; - readonly ABORT_ERR: 20; - readonly URL_MISMATCH_ERR: 21; - readonly QUOTA_EXCEEDED_ERR: 22; - readonly TIMEOUT_ERR: 23; - readonly INVALID_NODE_TYPE_ERR: 24; - readonly DATA_CLONE_ERR: 25; -}; +declare var DOMException: Bun.__internal.UseLibDomIfAvailable< + "DOMException", + { + prototype: DOMException; + new (message?: string, name?: string): DOMException; + /** + * `options.name` defaults to `"Error"`. `options.cause`, when present, is + * stored as the exception's `cause`, like `new Error(message, { cause })`. + */ + new (message?: string, options?: { name?: string | undefined; cause?: unknown }): DOMException; + readonly INDEX_SIZE_ERR: 1; + readonly DOMSTRING_SIZE_ERR: 2; + readonly HIERARCHY_REQUEST_ERR: 3; + readonly WRONG_DOCUMENT_ERR: 4; + readonly INVALID_CHARACTER_ERR: 5; + readonly NO_DATA_ALLOWED_ERR: 6; + readonly NO_MODIFICATION_ALLOWED_ERR: 7; + readonly NOT_FOUND_ERR: 8; + readonly NOT_SUPPORTED_ERR: 9; + readonly INUSE_ATTRIBUTE_ERR: 10; + readonly INVALID_STATE_ERR: 11; + readonly SYNTAX_ERR: 12; + readonly INVALID_MODIFICATION_ERR: 13; + readonly NAMESPACE_ERR: 14; + readonly INVALID_ACCESS_ERR: 15; + readonly VALIDATION_ERR: 16; + readonly TYPE_MISMATCH_ERR: 17; + readonly SECURITY_ERR: 18; + readonly NETWORK_ERR: 19; + readonly ABORT_ERR: 20; + readonly URL_MISMATCH_ERR: 21; + readonly QUOTA_EXCEEDED_ERR: 22; + readonly TIMEOUT_ERR: 23; + readonly INVALID_NODE_TYPE_ERR: 24; + readonly DATA_CLONE_ERR: 25; + } +>; declare function alert(message?: string): void; declare function confirm(message?: string): boolean; diff --git a/test/integration/bun-types/bun-types.test.ts b/test/integration/bun-types/bun-types.test.ts index 05fa801f45e5..c8d1473ef5b3 100644 --- a/test/integration/bun-types/bun-types.test.ts +++ b/test/integration/bun-types/bun-types.test.ts @@ -368,20 +368,23 @@ describe("@types/bun integration test", () => { }); // Runs on debug builds too: spawning tsc over a single file is cheap, - // unlike the in-process LanguageService runs above. - describe("Bun.mmap", () => { - test("MMapOptions accepts offset and size", async () => { - const checkDir = join(TEMP_DIR, "mmap-options-check"); + // unlike the in-process LanguageService runs above. The fixture/ files carry + // the full assertions for these declarations; this is the check of them that + // a debug build still runs. + describe("tsc over a single file", () => { + test("Bun.mmap offset/size and the DOMException options object are accepted", async () => { + const checkDir = join(TEMP_DIR, "single-file-check"); const tsconfig = structuredClone(sourceTsconfig); - tsconfig.include = ["mmap-options.ts"]; + tsconfig.include = ["check.ts"]; tsconfig.compilerOptions.typeRoots = [join(BASE_FIXTURE_DIR, "node_modules", "@types")]; await mkdir(checkDir, { recursive: true }); await makeTree(checkDir, { "tsconfig.json": JSON.stringify(tsconfig, null, 2), - "mmap-options.ts": `const view = Bun.mmap("./data.bin", { shared: true, sync: false, offset: 4096, size: 1024 }); + "check.ts": `const view = Bun.mmap("./data.bin", { shared: true, sync: false, offset: 4096, size: 1024 }); view satisfies Uint8Array; Bun.mmap("./data.bin", { offset: 4096 }) satisfies Uint8Array; - Bun.mmap("./data.bin", { size: 1024 }) satisfies Uint8Array;`, + Bun.mmap("./data.bin", { size: 1024 }) satisfies Uint8Array; + new DOMException("boom", { name: "AbortError", cause: new Error("inner") }) satisfies DOMException;`, }); await using proc = Bun.spawn({ @@ -685,6 +688,22 @@ describe("@types/bun integration test", () => { line: "globals.ts:307:5", message: "Object literal may only specify known properties, and 'headers' does not exist in type 'string[]'.", }, + { + code: 2345, + line: "globals.ts:340:37", + message: + "Argument of type '{ name: string; cause: Error; }' is not assignable to parameter of type 'string'.", + }, + { + code: 2345, + line: "globals.ts:341:37", + message: "Argument of type '{ name: string; }' is not assignable to parameter of type 'string'.", + }, + { + code: 2345, + line: "globals.ts:342:37", + message: "Argument of type '{ cause: string; }' is not assignable to parameter of type 'string'.", + }, { code: 2345, line: "http.ts:43:24", diff --git a/test/integration/bun-types/fixture/globals.ts b/test/integration/bun-types/fixture/globals.ts index 0ca54f0153e1..c11dd0b48ca8 100644 --- a/test/integration/bun-types/fixture/globals.ts +++ b/test/integration/bun-types/fixture/globals.ts @@ -336,6 +336,14 @@ new Error("asdf", { cause: new Error("asdf"), }); +expectType(new DOMException("asdf", "AbortError")).is(); +expectType(new DOMException("asdf", { name: "AbortError", cause: err })).is(); +expectType(new DOMException("asdf", { name: "AbortError" })).is(); +expectType(new DOMException("asdf", { cause: "asdf" })).is(); +expectType(new DOMException().cause).is(); +// @ts-expect-error the second argument is a name or an options object +new DOMException("asdf", 20); + // @ts-expect-error this interface is defined top level in globals.d.ts so we // are making sure that .d.ts is a module and that anything top level doesn't // leak to userland