The TypeScript of your dreams

Issue #300.June 24, 2024.2 Minute read.
Bytes

A lot’s changed since we started this newsletter 4 years ago – but according to my gastroenterologist, the anxious pit I feel in my stomach every Sunday evening will probably last forever. I wouldn’t have it any other way though, thanks for reading 🫶.

Today’s issue: The Ouija board of the web, Emerson’s thoughts on next-gen build tools, and “brilliant yet horrible” CSS hacks.

Welcome to #300 🥂.


Eyeballs logo

The Main Thing

An old lady holding a knife behind her back while pointing at a rabbit

Death, taxes, and us in your inbox twice a week

The TypeScript of your dreams

We had a few different ideas for how to celebrate today’s 300th issue: rank our top 300 JavaScript frameworks, write haikus for each of our favorite 300 ESLint rules, or try to hold our breath for 300 seconds while waiting for Lerna to build.

But in the end, we decided to write about the 3 biggest features from last week’s TypeScript 5.5 release. That might seem a little random, but spending my entire weekend transforming 7,000 words of incredibly boring thorough release notes into an entertaining and informative story felt like the most fitting way to celebrate this milestone.

Plus, v5.5 isn’t just another run-of-the-mill TypeScript update – it’s arguably the biggest TS release since we started writing Bytes back in June 2020. Let’s break down why that is by taking a closer look at the three most interesting new features.

Feature #1: Inferred Type Predicates – After 10 years of jumping through hoops, developers can finally get correct inference for type refinements on arrays. Before v5.5, this code would cause an error:

function makeBirdCalls(countries: string[]) {
  // birds: (Bird | undefined)[]
  const birds = countries
    .map(country => nationalBirds.get(country))
    .filter(bird => bird !== undefined);

  for (const bird of birds) {
    bird.sing();  // error: 'bird' is possibly 'undefined'.
  }
}

Now, TypeScript is smart enough to know that we filtered out all of the undefineds, so the array only contains Birds. This will help you write less code and make TypeScript a lot less annoying.

Feature #2: JSDoc Improvements – In TS 5.5, you are now able to import type definitions in a JSDoc comment. Previously, this wasn’t possible if the type wasn’t available at runtime.

/** @import { SomeType } from "some-module" */

/**
 * @param {SomeType} myValue
 */
function doSomething(myValue) {
    // ...
}

Feature #3: Editor Reliability and Performance – In addition to runtime and compiler performance improvements, this release also improves the watch functionality. If you’re tired of hitting the Restart TypeScript Server button in VSCode multiple times a day, today is a great day.

Bottom Line: TypeScript 🤝 Bytes – both hitting big milestones with our best days still to come.

        

QA Wolf logo

Our Friends
(With Benefits)

A dog on a laptop with a headset

When your manager randomly puts you on QA testing duty

Get your team to 80% automated test coverage in less than 4 months

Thoroughly testing new features is like flossing – it’s important, it’s painful, and everyone lies about how much they actually do it.

Fortunately, QA Wolf takes testing off your plate. They can get you:

  • 80% test coverage in just four months – not years
  • Unlimited parallel test runs
  • 24-hour maintenance and on-demand test creation
  • Easy test exporting with no vendor lock-in

The benefit? No more manual e2e testing. No more slow QA cycles. No more bugs reaching production.

Schedule a demo to learn more.


Spot the Bug logo

Spot the Bug

Presented by Apryse

Their advanced data extraction tools make it easy to transform PDF content into actionable data, so you can train AI models, pull info from financial reports, and lots more.

const people = [
  { firstName: "Aaron", lastName: "Smith" },
  { firstName: "Émile", lastName: "Zola" },
  { firstName: "Charlotte", lastName: "Brown" },
  { firstName: "Beyoncé", lastName: "Knowles" },
  { firstName: "Ólafur", lastName: "Arnalds" },
  { firstName: "David", lastName: "Jones" },
  { firstName: "Zoë", lastName: "Deschanel" },
];

function sortAlphabetically(arr) {
  return arr.sort((a, b) => {
    if (a.firstName < b.firstName) {
      return -1;
    }

    if (a.firstName > b.firstName) {
      return 1;
    }

    return 0;
  });
}

sortAlphabetically(people);

Cool Bits logo

Cool Bits

  1. Kabir Oberai created a library called NodeSwift, which allows you to write Swift code that talks to Node.js libraries and vice versa – like the Ouija board of the web.

  2. Sentry is hosting a Live Discussion with 3 backend legends next month – Taylor Otwell (Founder of Laravel), Paul Copplestone (Founder of Supabase) and Søren Schmidt (CEO of Prisma). They’ll share how they think about growing open-source projects, the future of backend dev, and lots more. Taylor might even show off the orange Lambo️. RSVP here. [sponsored]

  3. Vercel just released v3.2 of their AI SDK, with improvements to how agents and embeddings work.

  4. Dan Vanderkam wrote an in-depth post about The journey of implementing the Inferred Type Predicates feature and getting the PR merged. It’s kind of like the behind-the-scenes DVD bonus features to TypeScript 5.5.

  5. Lea Verou wrote “a series of brilliant, horrible hacks” to help you get similar functionality to Inline Conditionals in CSS – which probably won’t be in browsers for another couple years.

  6. Sergii Gorbachov wrote about his team at Slack’s AI-Powered conversion from Enzyme to React Testing Library.

  7. Farm is a Rust-based build tool that claims to be faster than Vite and Rspack. I guess we’ll find out if Ralph Waldo Emerson was right when he said, “If you build a faster build tool, the world will beat a path to your door.”

  8. Tomasz Rewak created Spread Grid, a new library for creating high-performance grid-based applications.

  9. Mike Johnson wrote about how You don’t need React Compiler if you’re already using MobX and React. I didn’t fact-check this article to know if that’s actually true or not, but I like Mike’s confidence.

  10. Roblox ported React to Lua, along with a bunch of other JavaScript libraries. Like Roblox itself, I’m not totally sure what the point of this project is, but it seems fun.


Spot the Bug logo

Spot the Bug: Solution

Sponsored by Apryse

const people = [
  { firstName: "Aaron", lastName: "Smith" },
  { firstName: "Émile", lastName: "Zola" },
  { firstName: "Charlotte", lastName: "Brown" },
  { firstName: "Beyoncé", lastName: "Knowles" },
  { firstName: "Ólafur", lastName: "Arnalds" },
  { firstName: "David", lastName: "Jones" },
  { firstName: "Zoë", lastName: "Deschanel" },
];

function sortAlphabetically(arr) {
  return arr.sort((a, b) => {
    if (a.firstName < b.firstName) {
      return -1;
    }

    if (a.firstName > b.firstName) {
      return 1;
    }

    return 0;
  });
}

sortAlphabetically(people);

By default, string comparison in JavaScript is not language-sensitive (meaning it doesn’t take into account language-specific rules or special characters like accents), which results in the sorted list not being in the correct order.

The solution is to leverage Intl.Collator which enables language-sensitive string comparison.

function sortAlphabetically(arr) {
  const collator = new Intl.Collator("en", { sensitivity: "base" });
  return arr.sort((a, b) => collator.compare(a.firstName, b.firstName));
}