diff --git a/cli/dts/lib.dom.d.ts b/cli/dts/lib.dom.d.ts
index 04fa72459537a..c5eafbec80c9c 100644
--- a/cli/dts/lib.dom.d.ts
+++ b/cli/dts/lib.dom.d.ts
@@ -16,7 +16,7 @@ and limitations under the License.
///
-
+///
/////////////////////////////
/// Window APIs
diff --git a/cli/dts/lib.dom.extras.d.ts b/cli/dts/lib.dom.extras.d.ts
new file mode 100644
index 0000000000000..8d21ae5750f6a
--- /dev/null
+++ b/cli/dts/lib.dom.extras.d.ts
@@ -0,0 +1,148 @@
+// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license.
+
+/*
+ * This library contains DOM standards that are not currently included in the
+ * distributed `lib.dom.d.ts` file with TypeScript.
+ */
+
+///
+
+interface AbortSignal extends EventTarget {
+ readonly reason?: unknown;
+}
+
+declare interface URLPatternInit {
+ protocol?: string;
+ username?: string;
+ password?: string;
+ hostname?: string;
+ port?: string;
+ pathname?: string;
+ search?: string;
+ hash?: string;
+ baseURL?: string;
+}
+
+declare type URLPatternInput = string | URLPatternInit;
+
+declare interface URLPatternComponentResult {
+ input: string;
+ groups: Record;
+}
+
+/** `URLPatternResult` is the object returned from `URLPattern.exec`. */
+declare interface URLPatternResult {
+ /** The inputs provided when matching. */
+ inputs: [URLPatternInit] | [URLPatternInit, string];
+
+ /** The matched result for the `protocol` matcher. */
+ protocol: URLPatternComponentResult;
+ /** The matched result for the `username` matcher. */
+ username: URLPatternComponentResult;
+ /** The matched result for the `password` matcher. */
+ password: URLPatternComponentResult;
+ /** The matched result for the `hostname` matcher. */
+ hostname: URLPatternComponentResult;
+ /** The matched result for the `port` matcher. */
+ port: URLPatternComponentResult;
+ /** The matched result for the `pathname` matcher. */
+ pathname: URLPatternComponentResult;
+ /** The matched result for the `search` matcher. */
+ search: URLPatternComponentResult;
+ /** The matched result for the `hash` matcher. */
+ hash: URLPatternComponentResult;
+}
+
+/**
+ * The URLPattern API provides a web platform primitive for matching URLs based
+ * on a convenient pattern syntax.
+ *
+ * The syntax is based on path-to-regexp. Wildcards, named capture groups,
+ * regular groups, and group modifiers are all supported.
+ *
+ * ```ts
+ * // Specify the pattern as structured data.
+ * const pattern = new URLPattern({ pathname: "/users/:user" });
+ * const match = pattern.exec("/users/joe");
+ * console.log(match.pathname.groups.user); // joe
+ * ```
+ *
+ * ```ts
+ * // Specify a fully qualified string pattern.
+ * const pattern = new URLPattern("https://example.com/books/:id");
+ * console.log(pattern.test("https://example.com/books/123")); // true
+ * console.log(pattern.test("https://deno.land/books/123")); // false
+ * ```
+ *
+ * ```ts
+ * // Specify a relative string pattern with a base URL.
+ * const pattern = new URLPattern("/:article", "https://blog.example.com");
+ * console.log(pattern.test("https://blog.example.com/article")); // true
+ * console.log(pattern.test("https://blog.example.com/article/123")); // false
+ * ```
+ */
+declare class URLPattern {
+ constructor(input: URLPatternInput, baseURL?: string);
+
+ /**
+ * Test if the given input matches the stored pattern.
+ *
+ * The input can either be provided as a url string (with an optional base),
+ * or as individual components in the form of an object.
+ *
+ * ```ts
+ * const pattern = new URLPattern("https://example.com/books/:id");
+ *
+ * // Test a url string.
+ * console.log(pattern.test("https://example.com/books/123")); // true
+ *
+ * // Test a relative url with a base.
+ * console.log(pattern.test("/books/123", "https://example.com")); // true
+ *
+ * // Test an object of url components.
+ * console.log(pattern.test({ pathname: "/books/123" })); // true
+ * ```
+ */
+ test(input: URLPatternInput, baseURL?: string): boolean;
+
+ /**
+ * Match the given input against the stored pattern.
+ *
+ * The input can either be provided as a url string (with an optional base),
+ * or as individual components in the form of an object.
+ *
+ * ```ts
+ * const pattern = new URLPattern("https://example.com/books/:id");
+ *
+ * // Match a url string.
+ * let match = pattern.exec("https://example.com/books/123");
+ * console.log(match.pathname.groups.id); // 123
+ *
+ * // Match a relative url with a base.
+ * match = pattern.exec("/books/123", "https://example.com");
+ * console.log(match.pathname.groups.id); // 123
+ *
+ * // Match an object of url components.
+ * match = pattern.exec({ pathname: "/books/123" });
+ * console.log(match.pathname.groups.id); // 123
+ * ```
+ */
+ exec(input: URLPatternInput, baseURL?: string): URLPatternResult | null;
+
+ /** The pattern string for the `protocol`. */
+ readonly protocol: string;
+ /** The pattern string for the `username`. */
+ readonly username: string;
+ /** The pattern string for the `password`. */
+ readonly password: string;
+ /** The pattern string for the `hostname`. */
+ readonly hostname: string;
+ /** The pattern string for the `port`. */
+ readonly port: string;
+ /** The pattern string for the `pathname`. */
+ readonly pathname: string;
+ /** The pattern string for the `search`. */
+ readonly search: string;
+ /** The pattern string for the `hash`. */
+ readonly hash: string;
+}
diff --git a/cli/tests/integration/run_tests.rs b/cli/tests/integration/run_tests.rs
index 4c4b42142f7e2..09c09d103c0bc 100644
--- a/cli/tests/integration/run_tests.rs
+++ b/cli/tests/integration/run_tests.rs
@@ -991,6 +991,11 @@ itest!(lib_dom_asynciterable {
output: "lib_dom_asynciterable.ts.out",
});
+itest!(lib_dom_extras {
+ args: "run --quiet --unstable --reload lib_dom_extras.ts",
+ output: "lib_dom_extras.ts.out",
+});
+
itest!(lib_ref {
args: "run --quiet --unstable --reload lib_ref.ts",
output: "lib_ref.ts.out",
diff --git a/cli/tests/testdata/lib_dom_extras.ts b/cli/tests/testdata/lib_dom_extras.ts
new file mode 100644
index 0000000000000..c061bd36208ea
--- /dev/null
+++ b/cli/tests/testdata/lib_dom_extras.ts
@@ -0,0 +1,17 @@
+const { diagnostics, files } = await Deno.emit("/main.ts", {
+ compilerOptions: {
+ target: "esnext",
+ lib: ["esnext", "dom"],
+ },
+ sources: {
+ "/main.ts": `const as = new AbortSignal();
+ console.log(as.reason);
+
+ const up = new URLPattern("https://example.com/books/:id");
+ console.log(up);
+ `,
+ },
+});
+
+console.log(diagnostics);
+console.log(Object.keys(files).sort());
diff --git a/cli/tests/testdata/lib_dom_extras.ts.out b/cli/tests/testdata/lib_dom_extras.ts.out
new file mode 100644
index 0000000000000..8b5e7adb6d11a
--- /dev/null
+++ b/cli/tests/testdata/lib_dom_extras.ts.out
@@ -0,0 +1,2 @@
+[]
+[ "[WILDCARD]/main.ts.js", "[WILDCARD]/main.ts.js.map" ]
diff --git a/cli/tsc.rs b/cli/tsc.rs
index 67285ef7d01a1..499360722186f 100644
--- a/cli/tsc.rs
+++ b/cli/tsc.rs
@@ -88,6 +88,7 @@ pub static STATIC_ASSETS: Lazy> =
inc!("lib.dom.asynciterable.d.ts"),
),
("lib.dom.d.ts", inc!("lib.dom.d.ts")),
+ ("lib.dom.extras.d.ts", inc!("lib.dom.extras.d.ts")),
("lib.dom.iterable.d.ts", inc!("lib.dom.iterable.d.ts")),
("lib.es6.d.ts", inc!("lib.es6.d.ts")),
("lib.es2016.full.d.ts", inc!("lib.es2016.full.d.ts")),
diff --git a/cli/tsc/00_typescript.js b/cli/tsc/00_typescript.js
index e239cb79e0df8..360278539058e 100644
--- a/cli/tsc/00_typescript.js
+++ b/cli/tsc/00_typescript.js
@@ -38443,6 +38443,7 @@ var ts;
["dom", "lib.dom.d.ts"],
["dom.iterable", "lib.dom.iterable.d.ts"],
["dom.asynciterable", "lib.dom.asynciterable.d.ts"],
+ ["dom.extras", "lib.dom.extras.d.ts"],
["webworker", "lib.webworker.d.ts"],
["webworker.importscripts", "lib.webworker.importscripts.d.ts"],
["webworker.iterable", "lib.webworker.iterable.d.ts"],
diff --git a/tools/update_typescript.md b/tools/update_typescript.md
index 0b4d54b3349d8..e012c7f77e2c5 100644
--- a/tools/update_typescript.md
+++ b/tools/update_typescript.md
@@ -84,6 +84,12 @@ contextual awareness, it is the author's opinion that it is best to spend the
- We add `lib.dom.asynciterables.d.ts` because for some reason TypeScript
has not built these into the libraries. (See:
https://github.com/microsoft/TypeScript/issues/29867)
+ - We add `lib.dom.extras.d.ts` because TypeScript is often behind
+ supporting some DOM standards that Deno supports and when people use
+ `lib: ["dom", "deno.ns"]` they will get error messages that are confusing
+ when using libraries that take advantage of these standards. We add the
+ library to `lib.dom.d.ts`, so it is automatically included when using the
+ `dom` lib under Deno.
7. Based on the changes to the lib files, you will need to edit the map of lib
names to files in the TypeScript compiler (`deno/cli/tsc/00_typescript.js`).
@@ -104,7 +110,7 @@ contextual awareness, it is the author's opinion that it is best to spend the
maps `esnext.*` values to the ratified version of them to ensure they are
less "breaking" so you will want to make sure, like for `esnext.array` that
it points at `lib.esnext.array.d.ts`. You will also want to revert the
- deletion of `dom.asynciterables`.
+ deletion of `dom.asynciterables` and `dom.extras`.
8. For any new lib files that were added, but not included in the snapshot (e.g.
`lib.es####.full.d.ts`) add them to `STATIC_ASSETS` in `deno/cli/tsc.rs`.