Exploring the TypeScript-first architecture of modern frameworks

Rate this content
Bookmark

TypeScript goes beyond annotating syntax. We’ll explore how modern frameworks leverage type-safety at the project-level to empower better architecture, greater stability, and higher velocities.

25 min
21 Sep, 2023

Video Summary and Transcription

Hi, everyone. Today, I'll be showing you some of the features that modern frameworks implement or frameworks that leverage Typescript implement to improve the developer and user experience. I'll cover some of the features that Expo with Expo Router and Next.js with the AppRouter implements. Let's talk about setting up TypeScript in both Expo and Next.js. Both frameworks provide a TypeScript-first development experience. The most important feature is type safe routing, which enhances developer productivity and app stability. Frameworks provide a built-in link component for link generation. It reduces the risk of typos and throws type errors when linking to non-existent routes. In Expo, enable the .typed experiment and import the link component from the exporouter package. Expo supports static and dynamic routes, and throws errors for incorrect parameters. ExpoRouter provides hooks like UseSegments and UseRouter for more control. In Next.js, enable typedRoutes in the next config file. We can import the link component from the next link package and restart the dev server after updating the next config file. Next.js automatically generates route definitions and includes the type file in the TS config. Autocompletion is available for the href attribute, which can be a string or dynamic value. Next.js provides hooks like use router for static navigation and router.push to prevent redirection to broken routes. Catch all routes in type safe routing pose a challenge for enforcing type safety on the href attribute. TypeScript may not throw an error for routes that may be broken or lead to unwanted pages. Keep this in mind when working with catch all routes. Before a production build, route types should be in place to ensure accurate type definitions. Generating routes is an ongoing task that needs to happen at the right moment to avoid build-time errors. When implemented correctly, type-safe routes can elevate the developer experience by preventing broken links or dysfunctional routes. In Next.js, server components and client components have different limitations. Next.js provides automatic error checking for importing useState in server components and enforces the useClientDirective to prevent using client-related code in the wrong places. Next.js also ensures type safety by throwing errors for invalid segment config options and requiring the alt attribute for image components to improve accessibility. Config files in Expo and Next.js have different approaches to incorporating TypeScript, with Expo using the TS node require hook and Next.js supporting type checking through jsdoc in the config JS file. By enabling type-safe routing, we catch potential issues at compile time, ensuring robust routes and unbroken links. Many other frameworks and tools leverage TypeScript to empower developers and deliver error-free experiences to users.

Available in Español

1. Introduction to TypeScript in Next.js and Expo

Short description:

Hi, everyone. Today, I'll be showing you some of the features that modern frameworks implement or frameworks that leverage Typescript implement to improve the developer and user experience. I'll cover some of the features that Expo with Expo Router and Next.js with the AppRouter implements. Let's talk about setting up TypeScript in both Expo and Next.js. Both frameworks provide a TypeScript-first development experience. The most important feature is type safe routing, which enhances developer productivity and app stability.

Hi, everyone. I'm Lydia Helle and today I'll be showing you some of the features that modern frameworks implement or frameworks that leverage Typescript implement to not only improve the developer experience, but also the user experience. And I'm sure that you've heard of these features before, you may have used them. So this is kind of just to remind you that they exist to give them some appreciation. And maybe you haven't used them before, in which case I hope that this talk will be valuable.

So for this talk, I'll cover some of the features that Expo with Expo Router and Next.js with the AppRouter implements. Of course, there are other frameworks that implement Typescript as well and leverage similar features. I'll mention them in the end, but for now I'll just want to focus on Next.js and Expo. So before I dive into the TypeScript part of Next.js and Expo, I just wanted to quickly introduce Expo Router, if you haven't heard of it before, which is likely if you aren't really interested in native development. But Expo Router is a file-based router for native apps and for web apps. So we can use it to easily navigate between screens and routes and reuse components on Android, iOS and web. So it brings that file system routing that we may be used to on the web to all platforms. If you haven't used it before, I highly recommend just kind of reading through the documentation. You can quick-start an Expo Router project using the mpx create-expo-app command. I highly recommend using that template tab because then everything is already installed and it's just much easier to get started with it. I'll just assume that you've heard of Next.js already, which we can initialize using mpx create-next-app-latest. For this talk though, I'll focus on Next.js 13 and mainly the app router. Of course, if you're still using the pages router, which is completely fine. We also have a lot of TypeScript support there, but for now I'll just be focusing on the app router.

Let's talk about setting up TypeScript in both Expo and Next.js. Both Next.js and Expo provide a TypeScript-first development experience for building your React application. In Expo, starting Expo Router through that setup command I just mentioned, which again, I highly recommend, it automatically ships with TypeScript already installed and configured so we can just utilize all the features right away. In Next.js, when initializing a new project through the setup commands, it'll ask you whether you like to use TypeScript as the first question, and it's yes by default, so just click yes. So both frameworks have a very TypeScript-first approach. Of course also, both Next.js and Expo allow you to quickly implement TypeScript or add support for TypeScript by simply converting a file from JS to TypeScript or to TS, and this will automatically install all the necessary dependencies and configure your project so that you can use TypeScript right away in an already existing project.

Now the most important part, let's talk about the features that we get from having TypeScript enabled and set up. The most important one is type safe routing. So type safe routing enhances the developer productivity and generally your apps stability by ensuring the correctness of the route references throughout your entire application because traditionally developers had to explicitly define route paths and associate them with specific views or components, and this system of course works, this is how we've always done it, but is very susceptible to human error because the developer can easily mistype a path leading to broken links or if you're migrating routes or renaming them, it's pretty easy to accidentally miss some of the anchor tags that are still linking to that old route and that would have created a bunch of broken links. And this is where TypeScript and the concept of type safe routing comes into play because TypeScript that supports this will scan your project's file system and dynamically generates TypeScript types for every detected route. And this creates a type-safe environment based on the current state of your application every time you update it.

2. Link Component and Routing in Expo and Next.js

Short description:

Frameworks provide a built-in link component for link generation. It reduces the risk of typos and throws type errors when linking to non-existent routes. In Expo, enable the .typed experiment and import the link component from the exporouter package. Expo supports static and dynamic routes, and throws errors for incorrect parameters. ExpoRouter provides hooks like UseSegments and UseRouter for more control. In Next.js, enable typedRoutes in the next config file.

And to make the system even more developer-friendly, frameworks usually provide a built-in link component that is designed for link generation. And this component has an href attribute that uses these types that we generated in the previous step based on the file system. And your IDE can use this for autosuggestion, autofill, which reduces the risk of typos even more. And most importantly, if a developer attempts to link to a route that doesn't exist, it'll throw that type error during the build process.

So let's see how we can use this in Expo first. So in Expo we can utilize this by first ensuring that the experiment's .typed is enabled. And after we've done that, we can import the link component from the exporouter package. For the sake of this demo, I'll just create a few more routes, which we can do by creating a new file with the name of the route. So for example, contact and route.

So now when we use the link component with the href attribute, you initially won't see the types because we had to start the dev server. Because Expo uses the bundler's file watcher to automatically create route declarations, which we can see in this auto-generated expo types file. So you can see like static routes, dynamic routes, all that. And you can also see that Expo automatically included this file in the ts-config. So TypeScript knows to watch this file when we're using that link component. So now back to the link component, you'll see that we get the autocompleted routes. Change a route name, for example, about to team, you will instantly see that type error. So this is super useful. And we can either just see it in our IDE. Or, of course, when you're running that dev server, if you have many files, and you won't easily catch it in your editor. Expo also supports dynamic routes. So let's just quickly create one using brackets. So now when we're using the link component to link to a dynamic route, Expo would also throw an error if you're accidentally linking to a dynamic route with an incorrect parameter. For example, ID here should have been or lowercase ID here should have been ID. So that's also very useful. And additionally, ExpoRouter also comes with some hooks like UseSegments and UseRouter that allow you to get even more control over that routing behavior. So if we use the router from UseRouter, it could, for example, say like router.push, they also utilize the types that were just generated. So you can always be assured that your routes are correct even when redirecting or pushing all that kind of stuff.

Now it's in Next.js. Next.js provides a similar approach. So to enable types of routing, make sure that the experimental.typedRoutes is set to true in your next config file.

3. Importing Link Component and Next.js Routing

Short description:

We can import the link component from the next link package and restart the dev server after updating the next config file. Next.js automatically generates route definitions and includes the type file in the TS config. Autocompletion is available for the href attribute, which can be a string or dynamic value. Next.js provides hooks like use router for static navigation and router.push to prevent redirection to broken routes.

And then we can again import the link component this time from the next link package. And since we updated the next config file, we'll just have to restart the dev server, which will now again, scan our file system to automatically generate these route definitions in the next type file.

You can see here, it looks pretty similar to what we just saw. We have the static routes, dynamic routes, all that. And Next.js automatically includes this type file in the include field in your TS config. So again, Tadascript knows where to look. So we again get the autocompletion in the href attribute and the href can again be a string or this dynamic value.

For Next.js, we just have to import the route type from Next if we are using a dynamic value like this. And Next.js also comes with some hooks for static navigation. Also like use router. So we can use router.push and it'll show all the routes again. Yeah. To make sure that we don't redirect to a broken route.

4. Challenges with Catch All Routes

Short description:

Catch all routes in type safe routing pose a challenge for enforcing type safety on the href attribute. TypeScript may not throw an error for routes that may be broken or lead to unwanted pages. Keep this in mind when working with catch all routes.

One of the kind of downsides or more of like an edge case, I guess, or stuff to keep in mind is catch all routes. Because in essence, a catch all route is a kind of a wildcard mechanism. You know, it validates and matches any given routes. And this is a challenge for type safe routing, because if any route is deemed valid, how do you enforce type safety on the href attribute? So, you know, TypeScript gets a bit blindsided in those situations. Because it doesn't know whether a particular route corresponds to a dynamic page or not. So, now, we can essentially type any route. And it may be broken or it may lead to a page where we don't want people to go. TypeScript won't throw that error. So, it makes sense. And it is expected behavior. But just make sure. Like, keep that in mind that this might happen.

5. Importance of Route Types and Next.js Features

Short description:

Before a production build, route types should be in place to ensure accurate type definitions. Generating routes is an ongoing task that needs to happen at the right moment to avoid build-time errors. When implemented correctly, type-safe routes can elevate the developer experience by preventing broken links or dysfunctional routes. The next section will cover additional TypeScript features in Next.js that relate to rendering and data-fetching paradigms.

Another important thing to remember, and this is more for authors, but it's when types get generated. Because before a production build is triggered, which in most development environments happens in CI, the route types should already be in place. Because that helps ensure that the production build has access to the latest routes and most accurate type definitions.

So, generating routes isn't just like a one-off task. It kind of happens continuously. And it needs to happen at the right moment. Otherwise, you keep running into these type errors at build time.

So, to kind of sum up the type save route part, when implemented and managed correctly, it can really elevate the developer experience. Because despite developer's best efforts, sometimes we just need that safeguard mechanism to ensure that we don't inadvertently introduce broken links or dysfunctional routes.

So, the next section will be on just Next.js. Because Next.js also comes with additional TypeScript features that relate to the new rendering paradigms, data-fetching paradigms. And I'll be covering the ones that are currently supported. But just so you know, more features will be added in the future to enhance the developer experience even further.

6. TypeScript Support and Config Files in Next.js

Short description:

In Next.js, server components and client components have different limitations. Next.js provides automatic error checking for importing useState in server components and enforces the useClientDirective to prevent using client-related code in the wrong places. Next.js also ensures type safety by throwing errors for invalid segment config options and requiring the alt attribute for image components to improve accessibility. Config files in Expo and Next.js have different approaches to incorporating TypeScript, with Expo using the TS node require hook and Next.js supporting type checking through jsdoc in the config JS file.

The first one is related to the server components and client components. I won't explain what server components and client components are. If you aren't sure, I highly recommend you read the docs to kind of understand what they are. But long story short, we can't always use like we can't use lifecycle hooks or any client related code in server components.

So, first Next.js will automatically throw an error if you're importing useState in a component that hasn't been marked with the useClientDirective. And this is incredibly useful because we can't use hooks like useState or useEffect or anything that should be on the client and server components. So in most cases, you probably just forgot to make that component and client components. So this helps to ensure that we aren't forgetting that, which is pretty easy to do. And additionally, Next.js will also throw a type error if you've used the useClientDirective anywhere but on the top of your file. Like it'll tell you move it to the top of the file. And this is an easy one to forget or overlook. So having that additional type safety helps to avoid these confusing bugs that may have let us so many hours trying to debug such an easy thing.

Next.js also throws an error if the or if you have invalid values for the segment config options. So route segment options allow you to configure the behavior of a page, a layout, or a route handler by exporting variables. And those variables can only have specific values, as you can see here. So Next.js helps ensure that you're setting these exported variables to values that are actually valid, which is also very useful. Next.js TypeScript support also helps with accessibility, for example by requiring that the alt attribute is set on image components. And this means that whenever we use that image components, TypeScript will remind you to set the alt which is, you know, essential for screen readers and just overall web accessibility. It's often something that's overlooked by developers. So having this little nudge just helps to ensure that, you know, your web application is more inclusive by default.

And lastly, a small but important one is config files. So config files must be a JavaScript file as it doesn't get parsed by Babel or TypeScript. And the way that both Expo and Next.js handle this is a bit different. So in Expo to use TypeScript in their config files like webpack metro or app, you can use the TS node require hook, and you first have to install that. And this allows you to import a TypeScript file in the JS config file. So, for example, we can create one TypeScript at config.ts. We can import the Expo config type and then we can just write our config like we want to and it'll like auto deplete everything and then we can import this file in the app config JS using TS node. So now we still have a valid config file, but we also have that additional type safety at the cost of having an additional file, but that may be worth it. Now in Next.js, so Next.js' config JS allows you to add some type checking in your IDE using jsdoc. It's this like import line that you see here.

7. TypeScript Benefits and Conclusion

Short description:

By enabling type-safe routing, we catch potential issues at compile time, ensuring robust routes and unbroken links. Many other frameworks and tools leverage TypeScript to empower developers and deliver error-free experiences to users.

You may have seen before also in other frameworks or other tools. So now when we import it at the top of our file, we also have type safety. So this doesn't require an additional file, but it uses jsdoc.

So to wrap up this brief overview, we've just seen how Xfo and Next.js use TypeScript to improve the developer experience, which in turn also improves the user experience. And by enabling, you know, type safe routing, we can catch potential issues at compile time, ensuring our routes are robust, our links aren't broken, our applications are more resilient to human error.

Of course, there are many other frameworks and tools that leverage TypeScript offer similar features. To me, it just shows how the developer ecosystem is evolving towards a future where, you know, developers are empowered by their tools and we can deliver type error-free experiences to our users. So thank you for joining me today. I hope it was helpful. And have fun coding.

Check out more articles and videos

We constantly think of articles and videos that might spark Git people interest / skill us up or help building a stellar career

React Summit Remote Edition 2021React Summit Remote Edition 2021
33 min
Building Better Websites with Remix
Top Content
Remix is a new web framework from the creators of React Router that helps you build better, faster websites through a solid understanding of web fundamentals. Remix takes care of the heavy lifting like server rendering, code splitting, prefetching, and navigation and leaves you with the fun part: building something awesome!
Remix Conf Europe 2022Remix Conf Europe 2022
23 min
Scaling Up with Remix and Micro Frontends
Top Content
Do you have a large product built by many teams? Are you struggling to release often? Did your frontend turn into a massive unmaintainable monolith? If, like me, you’ve answered yes to any of those questions, this talk is for you! I’ll show you exactly how you can build a micro frontend architecture with Remix to solve those challenges.
React Summit 2023React Summit 2023
32 min
Speeding Up Your React App With Less JavaScript
Top Content
Too much JavaScript is getting you down? New frameworks promising no JavaScript look interesting, but you have an existing React application to maintain. What if Qwik React is your answer for faster applications startup and better user experience? Qwik React allows you to easily turn your React application into a collection of islands, which can be SSRed and delayed hydrated, and in some instances, hydration skipped altogether. And all of this in an incremental way without a rewrite.
JSNation 2022JSNation 2022
28 min
Full Stack Documentation
Top Content
Interactive web-based tutorials have become a staple of front end frameworks, and it's easy to see why — developers love being able to try out new tools without the hassle of installing packages or cloning repos.But in the age of full stack meta-frameworks like Next, Remix and SvelteKit, these tutorials only go so far. In this talk, we'll look at how we on the Svelte team are using cutting edge web technology to rethink how we teach each other the tools of our trade.
GraphQL Galaxy 2021GraphQL Galaxy 2021
32 min
From GraphQL Zero to GraphQL Hero with RedwoodJS
Top Content
We all love GraphQL, but it can be daunting to get a server up and running and keep your code organized, maintainable, and testable over the long term. No more! Come watch as I go from an empty directory to a fully fledged GraphQL API in minutes flat. Plus, see how easy it is to use and create directives to clean up your code even more. You're gonna love GraphQL even more once you make things Redwood Easy!
Remix Conf Europe 2022Remix Conf Europe 2022
37 min
Full Stack Components
Top Content
Remix is a web framework that gives you the simple mental model of a Multi-Page App (MPA) but the power and capabilities of a Single-Page App (SPA). One of the big challenges of SPAs is network management resulting in a great deal of indirection and buggy code. This is especially noticeable in application state which Remix completely eliminates, but it's also an issue in individual components that communicate with a single-purpose backend endpoint (like a combobox search for example).
In this talk, Kent will demonstrate how Remix enables you to build complex UI components that are connected to a backend in the simplest and most powerful way you've ever seen. Leaving you time to chill with your family or whatever else you do for fun.

Workshops on related topic

React Advanced Conference 2021React Advanced Conference 2021
174 min
React, TypeScript, and TDD
Top Content
Featured WorkshopFree
ReactJS is wildly popular and thus wildly supported. TypeScript is increasingly popular, and thus increasingly supported.

The two together? Not as much. Given that they both change quickly, it's hard to find accurate learning materials.

React+TypeScript, with JetBrains IDEs? That three-part combination is the topic of this series. We'll show a little about a lot. Meaning, the key steps to getting productive, in the IDE, for React projects using TypeScript. Along the way we'll show test-driven development and emphasize tips-and-tricks in the IDE.
DevOps.js Conf 2024DevOps.js Conf 2024
163 min
AI on Demand: Serverless AI
Top Content
Featured WorkshopFree
In this workshop, we discuss the merits of serverless architecture and how it can be applied to the AI space. We'll explore options around building serverless RAG applications for a more lambda-esque approach to AI. Next, we'll get hands on and build a sample CRUD app that allows you to store information and query it using an LLM with Workers AI, Vectorize, D1, and Cloudflare Workers.
React Advanced Conference 2022React Advanced Conference 2022
148 min
Best Practices and Advanced TypeScript Tips for React Developers
Top Content
Featured Workshop
Are you a React developer trying to get the most benefits from TypeScript? Then this is the workshop for you.In this interactive workshop, we will start at the basics and examine the pros and cons of different ways you can declare React components using TypeScript. After that we will move to more advanced concepts where we will go beyond the strict setting of TypeScript. You will learn when to use types like any, unknown and never. We will explore the use of type predicates, guards and exhaustive checking. You will learn about the built-in mapped types as well as how to create your own new type map utilities. And we will start programming in the TypeScript type system using conditional types and type inferring.
JSNation 2023JSNation 2023
170 min
Building WebApps That Light Up the Internet with QwikCity
Featured WorkshopFree
Building instant-on web applications at scale have been elusive. Real-world sites need tracking, analytics, and complex user interfaces and interactions. We always start with the best intentions but end up with a less-than-ideal site.
QwikCity is a new meta-framework that allows you to build large-scale applications with constant startup-up performance. We will look at how to build a QwikCity application and what makes it unique. The workshop will show you how to set up a QwikCitp project. How routing works with layout. The demo application will fetch data and present it to the user in an editable form. And finally, how one can use authentication. All of the basic parts for any large-scale applications.
Along the way, we will also look at what makes Qwik unique, and how resumability enables constant startup performance no matter the application complexity.
React Summit 2023React Summit 2023
106 min
Back to the Roots With Remix
Featured Workshop
The modern web would be different without rich client-side applications supported by powerful frameworks: React, Angular, Vue, Lit, and many others. These frameworks rely on client-side JavaScript, which is their core. However, there are other approaches to rendering. One of them (quite old, by the way) is server-side rendering entirely without JavaScript. Let's find out if this is a good idea and how Remix can help us with it?
Prerequisites- Good understanding of JavaScript or TypeScript- It would help to have experience with React, Redux, Node.js and writing FrontEnd and BackEnd applications- Preinstall Node.js, npm- We prefer to use VSCode, but also cloud IDEs such as codesandbox (other IDEs are also ok)
Node Congress 2024Node Congress 2024
83 min
Deep TypeScript Tips & Tricks
Top Content
Workshop
TypeScript has a powerful type system with all sorts of fancy features for representing wild and wacky JavaScript states. But the syntax to do so isn't always straightforward, and the error messages aren't always precise in telling you what's wrong. Let's dive into how many of TypeScript's more powerful features really work, what kinds of real-world problems they solve, and how to wrestle the type system into submission so you can write truly excellent TypeScript code.