The Temporal API is Moving Forward!

The Temporal API has made great progress since I wrote my article on it, The Temporal API Is Awesome.

The major milestones have been:

What does this mean and why is this important?

Standards

Last time we explored this, we saw that, for the TC39 proposal to reach stage 4, there were two main outstanding issues:

There's only 1 issue left now! As of 2023-10-272 the IETF proposal has been accepted and is now a standard.

One down, one to go. And that last issue is mostly done, too.

Things are looking good over here :)

Deno

Deno has added first-class support for it3 in its 1.40.0 release. This is yet another major player in the JS world showing great interest in this API moving forward.

But it also adds immediate value to devs. The Temporal API was already available in Deno before 1.40.0 β€”since Deno uses V8 under the hoodβ€” behind a V8-specific feature flag: --v8-flags=--harmony-temporal. You could do this:

$ deno repl --v8-flags=--harmony-temporal
Deno 1.39.0
exit using ctrl+d, ctrl+c, or close()
> Temporal.Now.instant().toString()

"2024-02-10T16:52:04.823920896Z"

You can now do this:

$ deno repl --unstable-temporal
Deno 1.39.0
exit using ctrl+d, ctrl+c, or close()
> Temporal.Now.instant().toString()

"2024-02-10T16:52:51.623122944Z"

So we --unstable-temporal instead of --v8-flags=--harmony-temporal. Big deal.

But wait β€” there's more under the hood. Looking at the relevant PR4, the main changes to Deno's codebase are:

Alright, let's give this a try.

First, let's move on from the repl and write an actual file, deno.ts:

console.log('πŸ•œ', 'Instant as string')
const instantAsString: string = Temporal.Now.instant().toString()
console.log(instantAsString)

console.log()
console.log('πŸ•ž', 'Instant as Instant β€” inferred')
const instantAsInstantInferred = Temporal.Now.instant()
console.log('Run-time type:', Object.getPrototypeOf(instantAsInstantInferred))
console.log(instantAsInstantInferred)

console.log()
console.log('πŸ•£', 'Instant as Instant β€” explicitly typed')
const instantAsInstant: Temporal.Instant = Temporal.Now.instant()
console.log('Run-time type:', Object.getPrototypeOf(instantAsInstant))
console.log(instantAsInstant)

console.log()
console.log('πŸ•Ÿ', 'Instant as boolean β€” this should blow up')
const instantAsBoolean: boolean = Temporal.Now.instant()
console.log('Run-time type:', Object.getPrototypeOf(instantAsBoolean))
console.log(instantAsBoolean)

And let's run it with version 1.39.0

$ deno --version
deno 1.39.0 (release, x86_64-unknown-linux-gnu)
v8 12.0.267.8
typescript 5.3.3

$ deno run --v8-flags=--harmony-temporal deno.ts
πŸ•œ Instant as string
2024-02-10T17:57:43.596431872Z

πŸ•ž Instant as Instant β€” inferred
Run-time type: Object [Temporal.Instant] {}
Instant [Temporal.Instant] {}

πŸ•£ Instant as Instant β€” explicitly typed
Run-time type: Object [Temporal.Instant] {}
Instant [Temporal.Instant] {}

πŸ•Ÿ Instant as boolean β€” this should blow up
Run-time type: Object [Temporal.Instant] {}
Instant [Temporal.Instant] {}

So far, so good. But take a look at the last test:

console.log('πŸ•Ÿ', 'Instant as boolean β€” this should blow up')
const instantAsBoolean: boolean = Temporal.Now.instant()

Indeed, this should blow up. We're trying to assign an Instant to a boolean, but nothing's complaining about this. We actually need to deno check to type-check our code:

$ deno check deno.ts 
Check file:///.../deno.ts
error: TS2304 [ERROR]: Cannot find name 'Temporal'.
const instantAsString: string = Temporal.Now.instant().toString()
                                ~~~~~~~~
    at file:///.../deno.ts:2:33

TS2304 [ERROR]: Cannot find name 'Temporal'.
const instantAsInstantInferred = Temporal.Now.instant()
                                 ~~~~~~~~
    at file:///.../deno.ts:7:34

TS2503 [ERROR]: Cannot find namespace 'Temporal'.
const instantAsInstant: Temporal.Instant = Temporal.Now.instant()
                        ~~~~~~~~
    at file:///.../deno.ts:13:25

TS2304 [ERROR]: Cannot find name 'Temporal'.
const instantAsInstant: Temporal.Instant = Temporal.Now.instant()
                                           ~~~~~~~~
    at file:///.../deno.ts:13:44

TS2304 [ERROR]: Cannot find name 'Temporal'.
const instantAsBoolean: boolean = Temporal.Now.instant()
                                  ~~~~~~~~
    at file:///.../deno.ts:19:35

Found 5 errors.

Kaboom it went, but not only where we expected it to β€” everything blew up! Dang, this isn't very helpful. Let's try this again, but with 1.40.0 instead:

$ deno --version
deno 1.40.0 (release, x86_64-unknown-linux-gnu)
v8 12.1.285.6
typescript 5.3.3

$ deno --unstable-temporal run deno.ts
# Same output as with 1.39.0. as before. Omitting it here to reduce noise.

$ deno check deno.ts
Check file:///.../deno.ts
error: TS2322 [ERROR]: Type 'Instant' is not assignable to type 'boolean'.
const instantAsBoolean: boolean = Temporal.Now.instant()
      ~~~~~~~~~~~~~~~~
    at file:///.../deno.ts:19:7 

Now would you look at that! This is some actually useful feedback.

If you're curious, these types exist in tsc/dts/lib.deno.unstable.d.ts. And that file is over 4200 lines long! Sure comes in handy not to have to deal with that ourselves.

Final Words

I'm not usually so inclined to provide updates on things, as there are a bunch of newsletters out there already that do a great job at this; but I've grown a strong interest in the evolution of JavaScript over the years and am particularly passionate about some emerging html, css and js standards β€” specially understanding them in depth rather than just the "hey this is out there" or "this has happened".

I believe there's value in sharing these in-depth articles here, but am not sure about whether sending updates such as this one in the newsletter would be useful to you. Do you think it would be? Do you think it wouldn't? I'd love to hear your feedback! You can reach out to me at hey@taro.codes.

And if you liked what you read, subscribe to my newsletter :)

Next up in my list is an article exploring Web Components and paraphernalia (omg this stuff is awesome), a piece with some strong opinions on unit and integration testing and quite possible one on MongoDB.

A newsletter for programmers

Yo! This is Taro. I've been doing JavaScript for years and TypeScript for years. I have experience with many programming languages, libraries, frameworks; both backend and frontend, and in a few company roles/positions.

I learned a few things over the years. Some took more effort than I wish they had. My goal with this blog and newsletter is to help frontend and backend developers by sharing what I learned in a friendlier, more accessible and thorough manner.

I write about cool and new JavaScript, TypeScript and CSS features, architecture, the human side of working in IT, my experience and software-related things I enjoy in general.

Subscribe to my newsletter to receive notifications when I publish new articles, as well as some newsletter-exclusive content.

No spam. Unsubscribe at any time. I'll never share your details with anyone. 1 email a week at most.

Success!
You have subscribed to Taro's newsletter
Shoot!
The server blew up. I'll go get my fire extinguisher β€” please check back in 5.