fork you... Or rather, fork us

Issue #50.May 31, 2021.2 Minute read.

Blink 182 - the microsoft version

Nobody likes you when you’re 4.3

TypeScript releases v4.3

TypeScript blessed us with v4.3 last week, and it came with an announcement post that’s like a 19th-Century Russian novel mixed with a CVS receipt — it just keeps going.

Quick review: If you’re new to TypeScript-land, just know that it allows you to add types to your code so that you can catch mistakes like logic errors and typos. It’s kind of like your little league baseball coach who “only yells at you because he cares”, but with less of a drinking problem.

Let’s get to the highlights of TS 4.3:

  • New override keyword — If you mark a method with override, it’ll check to see if a method with the same name exists in the base class. That prevents common errors that come up when you can’t make it clear whether you meant to add a totally new method or override an existing one. It also comes with a new --noImplicitOverride flag, which gives TypeScript permission to (lovingly) yell at you if you try to override a method without using override.

  • Separate write types on properties — It was always pretty tricky to model APIs that convert passed-in values before storing them, because TypeScript forced you to choose between optimizing for reading values or writing values. But now you can specify types for reading and writing to properties. Best of both worlds.

  • Template String Type Improvements — These are new-ish types that either construct new string-like types by concatenating or they match patterns of other string-like types. TypeScript 4.3 makes a few improvements to how & when TypeScript infers these TSTs.

The Bottom Line

Like blink-182, many people kind of hate TypeScript at first, but grow to love and appreciate it over time. And v4.3 is another solid release that continues to shore up various typing edge cases.


Just ship it [Sponsored]

Build internal tools 10x faster with Retool

It finally happened. Your boss approached you and needs some “internal tools thrown together” because the suits upstairs want to make some “data-driven decisions.”

No problem, you think, should only take a few days. But then you spend the next month hacking together a wide variety of your company’s data sources, only to realize at the last minute that you never considered auth, and (oh crap) the whole thing looks terrible. Should’ve used Retool.

Retool started when a few developers realized that all internal tools are made up of the same basic pieces — tables, lists, charts, forms, maps, wizards (I’m a wot?), etc. So they made a rad product that abstracts away all the annoying parts of building those tools, while still giving you the flexibility to write custom JavaScript anywhere in the app.

And thanks to their pretty generous free tier, I can finally tell my mom that I’m a 10x (internal tools) developer.


Who’s that testing framework…?_

Jest 27 Has New Defaults

The web’s most popular JavaScript testing framework released v27 last week — their first major release to feature significant breaking changes in over two years (good thing fixing breaking changes in my testing framework is my kink).

The big news here is that Jest is changing the default test environment from "jsdom" to "node". There’s a lot that went into this, but the tl;dr is that most developers will see a big performance boost because they’ll no longer be unknowingly using an expensive DOM environment that they (usually) don’t need.

Other new stuff:

  • You can now interactively step through failed tests one at a time (sounds like my parent-teacher conferences in middle school)

  • You can now do inline snapshots without having to use Prettier as a mandatory pre-requisite (one of Jest’s most-requested features)

  • The recently-updated and much improved fake timers implementation became the default in Jest 27 (it was previously opt-in)

  • Initialization per test file is almost 70% faster than it was in Jest 26 👏

The Bottom Line

This release addresses some longstanding performance concerns and marks the first time that the testing framework has changed any defaults since mid-2016 — AKA back when Jest was on version 15 and Jess was on jury duty in Season 5 of New Girl.

Can’t wait to see what Jest looks like when Zooey Deschanel’s newest quirky sitcom is airing in 2026.

Cool Bits

  1. Flow, Facebook’s OG static type checker, wrote about its future direction last week. TL;DR — “We’re definitely still open source, but if you want to contribute, it needs to exactly match Facebook’s needs. Otherwise, fork you… Or rather, fork us.” Um, excuse me, Flow?

  2. Maxence wrote about scaling a large Vue app that he’s been working on for 3 years and is over 650k lines of code. 350k more lines to go before Evan You awards him the esteemed rank of VueLord™ and teaches him all the secret Vue cheat codes.

  3. Node.js turned 12 years old last week, and Ryan Dahl didn’t even show up for his child’s birthday party (typical). Rumor has it that he did send dino-shaped balloons though.

  4. Datadog released their 2021 State of Serverless report, which will probably make you wish you knew more about serverless. [Sponsored]

  5. V8 introduced Sparkplug — its new, non-optimizing compiler for JavaScript that improves V8 performance on real-world benchmarks by 5–15%.

  6. Florian wrote a great deep dive on Rust for Node.js developers. Not quite as many Salad Fingers references as we would’ve liked to see, but there’s always next time.

  7. Alex built tRPC — a super slick TypeScript toolkit for building end-to-end, type-safe APIs. Their second-choice for a name was Slick-Rick-API-Builder, but they decided against it at the last minute. Our loss.

  8. Boring Avatars is a tiny React library that generates custom, SVG-based avatars from any username and color palette. It’s also what most people said when they watch the Fern Gully remake highest-grossing movie of all time.

JS Tip: == vs ===

When writing software, the simpler solution is almost always the better one. If in order to use a feature I first have to learn and remember a list of rules pertaining to it, I try my best to avoid it. Not because that feature might not be valuable to know, but because I don’t trust myself to remember every nuanced rule. That logic is the primary decision to why I always use triple equals (===) over double equals (==). They both accomplish similar things, but the Pit of Success for triple equals is much larger, let’s see why.

Identity Operator (triple equals, ===)

When using triple equals ===, there are two rules you need to remember - strict equality (for when you’re comparing primitive values) and reference equality (for when you’re comparing reference values).

Strict Equality

Strict equality checks that both the type (number, string, boolean, etc) and the value are the same. If the type is the same but not the value, you’ll get false. If the value is the same but not the type, you’ll get false. If both the value and the type are the same, you’ll get true.

5 === 5 // true. Same type, same value.
5 === 4 // false. Same type, different values.
5 === "5" // false. Different type, same value.

true === true // true. Same type, same value.
true === false // false. Same type, different values.
true === 'true' // false. Different type, same value.

Seems simple enough, but as mentioned earlier this rule breaks down when we start to compare reference values (or values that aren’t primitives).

Reference Equality

As we saw in the previous example, primitives are compared by their value. However, if you use triple equals with reference values, it’s going to compare the references (or spots in memory).

{} === {} // false. Same type, similar value, different reference. ❌
[] === [] // false. Same type, similar value, different reference. ❌
{ name: 'Meg' } === { name: 'Meg' } // false. Same type, similar value, different reference. ❌

Even though each of the examples above has the same type and what appears to be the same value, because they’re reference values, JavaScript compares the references in memory, not the actual value. In each of the examples the references or locations in memory are different, which is why we always get false.

We can see this further by assigning two variable to the same reference in memory and then using the identity operator on them.

const user = {
  name: 'Tyler'

const person = user

person === user // true. Same type, same value, same reference.

In the example both person and user are referencing the same spot in memory, which is why we get true.

In summary, when using the Identity Operator (===), assuming you know about reference equality, everything just works as you’d expect. Here’s an equality table to prove it.

Triple equals equality table

Equality Operator (double equals, ==)

Unlike the Identity Operator (===), unless you’re very familiar with it, odds are the Equality Operator (==) doesn’t behave as you’d expect. Here are just some examples,

"1" == 1 // true
null == undefined // true
0 == '' // true
'0' == false // true
[1] == true // true 🤷‍♂️

So what exactly is going on here? Notice that each comparison is being made between different types. As we saw earlier with the Identity Operator (===), all of these would return false since they’re all of different types. With the Equality Operator (==), it’s not that simple. Instead of returning false when the types don’t match, it’ll attempt to convert them into the same type.

So in the first example, "1" == 1 because the JavaScript engine will convert the String “1” to Number 1 which then evaluates to 1 == 1 which is true.

It’s that type coercion stage which makes the Equality Operator (==) so unpredictable. Here’s the same equality table we saw before except now in terms of ==.

Double equals equality table

If you and anyone who works on your codebase is confident in all of JavaScript’s type coercion rules, feel free to use whichever operator you’d like. However, if you’re like me and you’d rather use the tool that works how you’d expect, stick with the Identity Operator (===).