47.6 RTL Support and Direction-Aware Types

Right, so you’ve built a beautiful, responsive UI. It looks perfect. Until someone views it in a language that reads right-to-left, like Arabic or Hebrew, and suddenly your meticulously placed “Add to Cart” button is floating in the void like a lost astronaut. The web is a global place, and assuming left-to-right (LTR) is a fantastic way to look amateurish to a huge portion of your audience. Thankfully, CSS does most of the heavy lifting here with the dir attribute and the direction property. Our job in TypeScript isn’t to reimplement that logic, but to model it, to make our components direction-aware and our functions robust enough to handle the flip. We’re adding type-safety to a design paradigm.

47.5 Typing Date and Number Formatters

Right, let’s talk about making your dates and numbers look like they belong on this planet. You’ve probably reached for Intl.DateTimeFormat and Intl.NumberFormat and thought, “This is great! I’ll just… uh…” and then your TypeScript compiler started screaming at you. That’s because these APIs are incredibly powerful, but their types are a glorious mess of string literals and overloads. TypeScript knows what’s valid, but it often refuses to hold your hand. It’s our job to be smarter than the average type assertion.

47.4 ARIA Attribute Types in React and the DOM

Right, let’s talk about ARIA. You’ve probably heard the mantra: “No ARIA is better than bad ARIA.” It’s good advice, but it’s led to a weird fear of using it at all. The truth is, when you’re building a complex, dynamic web app, you need ARIA to bridge the gap between what your div-soup looks like and what it actually is for a screen reader user. TypeScript, being the wonderfully pedantic friend it is, can actually help you write good ARIA instead of avoiding it.

47.3 Ensuring Translation Keys Exist at Compile Time

Right, so you’ve decided you don’t want your app to greet your German users with a friendly, debug-mode-style "homepage.header.welcome_message" instead of an actual “Willkommen”. We’ve all been there. The classic i18n (internationalization) problem is that your translation files are just loose JSON objects living out in the wild, and your code is just making a hopeful, stringly-typed request for a key that might not exist. TypeScript’s entire reason for being is to catch this exact class of error at compile time, not in your user’s console. So let’s use it.

47.2 Type-Safe i18n with next-intl and i18next

Right, let’s talk about making your app speak human. Not just a human, but many humans, in their own languages and formats. And we’re going to do it without resorting to a brittle mess of string keys and hope. We’re using TypeScript, for heaven’s sake. We have a type system; let’s make it earn its keep. The core problem with most i18n setups is that your translation files are a black box. You have a key like homepage.greeting and you just… hope that the value for that key exists and has the right number of placeholders. It’s like sending a junior developer to a meeting with a sticky note that just says “ask about the thing.” It’s a strategy, but not a good one.

47.1 Typing Locale Strings and Translation Keys

Right, let’s talk about something that starts with the best intentions and often ends in a tangled mess of stringly-typed despair: managing translation keys. You’ve decided to not hardcode every user-facing string, which is fantastic. But if you’re just doing t('some_key') all over your codebase, you’ve traded one problem for another. You now have a codebase littered with invisible dependencies on a JSON file you need to pray you spelled correctly. TypeScript exists precisely to save us from this particular flavor of self-inflicted pain.

— joke —

...