[whatwg/dom] Support `Temporal.Duration` as an argument to timeout-related APIs (Issue #1458)

lgarron created an issue (whatwg/dom#1458)

### What problem are you trying to solve?

Across various shells and programming languages, there are various methods to specify a duration for a timeout, and both seconds (e.g. `sleep` in most shells) and milliseconds (e.g. `setTimeout(…)` and `AbortSignal.timeout(…)` in the DOM API are common to encounter. If someone is not highly familiar with JS, the following may plausibly look like they do the same:

```shell
# shell
sleep 1
curl --connect-timeout 1 https://example.com
````

```js
setTimeout(() => {
  const request = fetch("https://api.example.com", {signal: AbortSignal.timeout(1)});
  // …
}, 1);
```

However, the latter uses timeouts that differ by a factor of 1,000. This kind of code also generally tends to be subject to more race conditions, making it plausible that that this kind of mistake is discovered well after it is initially coded.

This is not necessarily a huge stumbling block, but I think most programmers have experienced friction like this when switching between ecosystems and programming languages with contradicting conventions.

Some languages/standard libraries (e.g. [`thread::sleep(…)`](https://doc.rust-lang.org/std/thread/fn.sleep.html) in Rust) require a timeout argument to be specified as a value that is much more common to construct in an unmistakable way (e.g. `time::Duration::from_millis(10)` in the example in the Rust docs linked above).

JavaScript must keep backwards compatibility for timeouts that accept milliseconds, but it can improve the situation by accepting `Temporal.Duration` values as arguments.

### What solutions exist today?

Being careful? Using a value like `1_000` or `const TIMEOUT_MILLISECONDS = 1_000` can improve readability, but:

1. You already have to be aware of this in order to remember to do it.
2. There are number like 15 that do not "obviously" represent just one of milliseconds (could mean just under one frame at 60fps) or seconds (could mean ¼ minute) at first glance.

### How would you solve it?

Allow the following methods to accept a [`Temporal.Duration`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/Duration) in addition to accepting a numeric value in milliseconds:

- `setTimeout(…, timeout, …)`
- `setInterval(…, timeout, …)`
- `AbortSignal.timeout(timeout)`

This allows writing the following code, with a much more unmistakeable meaning:

```js
AbortSignal.timeout(Temporal.Duration.from({ seconds: 1 }))
```

Linters could further enforce the use of `Temporal.Duration` as an argument in codebases that would like to prioritize this convention.

There are also additional opportunities to update APIs related to animation, but I think the ones above are most high-value and a great starting point for using `Temporal` in the DOM API.

### Anything else?

I can see two "obvious" ways of implementing `Temporal.Duration` as a timeout value in these cases.

- Accept *only* instances of the built-in `Temporal.Duration`.
- Accept any object that has a `.total(…)` method, and specify that the value of `.total("milliseconds")` is used to convert the parameter into a value to be interpreted as milliseconds.

I think the former would prevent polyfills and ponyfills from working without shenanigans (e.g. hooking up conditional prototype chains), so it would would certainly make it annoying (at least in the short term).

The latter seems relatively natural to me. It also might benefit from specifying a concept that can be reused in the future. Similar to ecosystems conventions (e.g. TypeScript types) like "Promise-like", this might be "Duration-like" or "total duration provider".

-- 
Reply to this email directly or view it on GitHub:
https://github.com/whatwg/dom/issues/1458
You are receiving this because you are subscribed to this thread.

Message ID: <whatwg/dom/issues/1458@github.com>

Received on Sunday, 15 March 2026 02:49:11 UTC