Code Computerlove logo Front End Tools & Docs

NoInfer: TypeScript 5.4's New Utility Type

Matt Pocock talks about a new utility type brought to TypeScript 5.4 called NoInfer. It does pretty much exactly what it sounds like it should: prevents TypeScript inferring types from inside a generic function.

Inferred Example
const returnWhatIPassedIn = <T>(value: T) => value;
const result = returnWhatIPassedIn("hello");

In this example, TypeScript infers the type of result to be "hello". But you could tell TypeScript not to infer the type with this new utility:

NoInfer Example
const returnWhatIPassedIn = <T>(value: NoInfer<T>) => value;
const result = returnWhatIPassedIn("hello");

This would result in the type being unknown. In order to get the specific type returned you would need to pass it, such as:

NoInfer Example
const result = returnWhatIPassedIn<"hello">("hello");

So why would you want to do this? One example would be where there is more than one place for TypeScript to infer the type from. This would result in both types being inferred where you might only want one. Matt has a full example on the blog post on TotalTypescript.

Jhey's Spot

This week, on Jhey's Spot: CSS-only input status updates via a fancy 'stroke':

See the Pen CSS Only Status Input Stroke by Jhey (@jh3y) on CodePen.

See the Codepen here. Also note that browsers implement the email spec fully, which means some weird combinations are technically correct, but you can provide your own pattern attribute to roll your own.

Node.js runs on Next.js!

When I first saw this I was a bit confused and thought Next.js somehow had built a way to run Node inside itself 🤯. Turns out that the Node.js site now runs on Next.js (and Vercel) and it has, apparently, been a long road (3 years!) to get there.

I will be the first to admit that it is a refreshing change as the Node.js site hasn't changed in years! It looks good and is completely open-source so you can see how it was all implemented.

As ever, Theo has a great breakdown video on how it has been created and looks in-depth at some of the clever techniques used by the Node.js team. Some of the highlights for me include the fact that they documented every piece of tech used to build it, and there are handy comments throughout the code to explain the reasoning behind why it was written that way.

Also to note that a lot of the effort to create the site was around contributors experience in getting it setup, running and making it as easy as possible to contribute to. What a refreshing take! Plus accessibility and full internationalisation.

Next.js 14.2

Next,js has a new update! 14.2 was out on the 11th April and includes some interesting new features changes:

  • Turbopack for Development (Release Candidate): 99.8% tests passing for next dev --turbo.
  • Build and Production Improvements: Reduced build memory usage and CSS optimizations.
  • Caching Improvements: Configurable invalidation periods with staleTimes.
  • Error DX Improvements: Better hydration mismatch errors and design updates.

Turbopack is supposed to be a much faster developer experience and you can opt in with next dev --turbo. Might be worth giving it a go as some of the benchmarking suggests vast improvements but be warned that problems may arise from Turbopack not being able to compile extra packages added to Next.js. It also includes Lightning CSS, which is becoming the industry standard for bundling/minifying CSS.

I will try to get around to updating the starter and playing around with it next week.

Another interesting part that may apply to us is a better tree-shaking optimisation:

We identified an optimization for the boundary between Server and Client Components that allows for tree-shaking unused exports. For example, importing a single Icon component from a file that has "use client" no longer includes all the other icons from that package. This can largely reduce the production JavaScript bundle size.

You can read the full release blog post here.

ECMAScript 2024 Takes Shape

The ECMAScript standard brings seven new features including array grouping, growable ArrayBuffers, and promises with resolvers.

Array Grouping

This is an interesting one. I always enjoy new array methods 🤓. Array grouping will allow you to provide a function (like map) that iterates over the array and returns an object with grouped arrays based on the outcome:

Array Grouping
const array = [1, 2, 3, 4, 5];
// Object.groupBy groups items by arbitrary key.
// In this case, we're grouping by even/odd keys
Object.groupBy(array, (num, index) => {
return num % 2 === 0 ? 'even': 'odd';
});
// => { odd: [1, 3, 5], even: [2, 4] }
// Map.groupBy returns items in a Map, and is useful for grouping
// using an object key.
const odd = { odd: true };
const even = { even: true };
Map.groupBy(array, (num, index) => {
return num % 2 === 0 ? even: odd;
});
// => Map { {odd: true}: [1, 3, 5], {even: true}: [2, 4] }</code></pre>

Promise.withResolvers

I can't say I've ever had to do this but this method allows you to decouple the resolve and reject handlers from a Promise (and the Promise itself) so you can use them wherever you need:

Promise.withResolvers
const { promise, resolve, reject } = Promise.withResolvers();

As an example, before this you would have to do something like:

Without Promise.withResolvers
let resolve, reject;
const promise = new Promise((res, rej) => {
resolve = res;
reject = rej;
});
asyncRequest(config, response => {
const buffer = [];
response.on('callback-request', id => {
promise.then(data => callback(id, data));
});
response.on('data', data => buffer.push(data));
response.on('end', () => resolve(buffer));
response.on('error', reason => reject(reason));
});

Read the article on the new features here and check out the other proposals (both past and present) here.

Astro Expressive Code

Ive switched the code blocks on this blog to use Astro Expressive Code. It was very simple to install and configure. I've changed a couple of properties and it looks great. It uses Shiki under-the-hood (as most syntax highlighters do) with some extras.

My projects on the go

  • Front End tools upgrade - need to get the tools working properly on the live site
  • Front End challenges website
  • API flattener tool needs upgrading
  • Keeping the starters upgraded!