Faster TypeScript builds with --isolatedDeclarations

Type-checking a TypeScript codebase can be slow, especially for monorepos containing lots of projects that each need to use the type checker to generate type declaration files. In this talk, we introduce — for the very first time — a new TypeScript feature we are working on called “Isolated Declarations” that allows DTS files to be generated without using the type checker at all! This opens the door to faster declaration generation in TypeScript itself, as well as in external tools written in other languages such as ESBuild and swc. You'll see how to use this new option, and maybe (just maybe) you’ll be convinced about the benefits of explicit return types! Most importantly, we will show how Isolated Declarations enables parallel builds to spread work across your CPU cores to significantly improve the build speed of your TypeScript projects.

Spanish audio is available in the player settings
Rate this content
Bookmark
Video Summary and Transcription
The video discusses how to speed up TypeScript builds, focusing on a new feature called isolated declarations. This feature addresses the issue of slow build performance, especially in monorepos, by enhancing parallelism. The speaker explains that TypeScript's isolated modules mode allows JavaScript emit without type checking dependency, making it a purely syntactic process. By cutting the dependency between declaration emit and typechecking, developers can unblock dependencies sooner. This is achieved by specifying all types in the TypeScript file, which isolated declarations facilitate. The video highlights that isolated declarations improve build times considerably, with tests showing up to a threefold improvement. Developers can choose to opt-in to this feature if they wish to improve their TypeScript build performance. The talk also mentions collaboration with Bloomberg, Google, and Microsoft in developing this feature, aiming for its release in the next half a year. Additionally, the video touches on the potential of isolated declarations to improve compatibility with other tools and promote transparency by requiring developers to write types in code.

This talk has been presented at TypeScript Congress 2023, check out the latest edition of this JavaScript Conference.

FAQ

The main focus of the talk is on improving build performance in TypeScript, especially in monorepos.

The talk discusses a new feature called 'isolated declarations,' which helps improve parallelism and build performance.

The isolated declarations feature aims to remove dependencies between type checking and declaration emit, allowing for greater parallelism and faster build times.

The potential impact of the isolated declarations feature on single project setups is still being explored, but there are limitations that need to be addressed in the TypeScript compiler first.

JavaScript emit is independent from type checking due to the 'isolated modules' mode, which allows each file to be transpiled from TypeScript to JavaScript individually.

In tests with a sample monorepo, the isolated declarations feature resulted in a threefold improvement in build times, reducing build times to single digits in some cases.

The speaker is Tiziano Cernico-Adragomir, a software engineer at Bloomberg and a TypeScript compiler contributor.

TypeScript performs three main tasks during the build process: type checking, declaration emit, and JavaScript emit.

Yes, developers can choose not to use the isolated declarations feature if they are satisfied with their current TypeScript build times.

The isolated declarations feature was developed in collaboration with Bloomberg, Google, and Microsoft.

1. Introduction to TypeScript Builds#

Short description:

Hello, everyone. Welcome to my talk, Speeding up TypeScript builds. I'm going to talk about build performance, especially in monorepos. We're developing an upcoming feature in collaboration with Bloomberg, Google, and Microsoft. The motivation for this feature is the complaints about build performance in TypeScript. We tried running the compiler in parallel, which resulted in significant performance gains for a 23-project mono repo.

Hello, everyone. Welcome to my talk, Speeding up TypeScript builds. My name is Tiziano Cernico-Adragomir. I'm a software engineer in Bloomberg in the TypeScript JavaScript infrastructure team, and I'm also a TypeScript compiler contributor.

And today I want to talk about build performance, especially build performance in monorepos. And we're going to talk about an upcoming feature of TypeScript that we've been developing in collaboration with Bloomberg, Google, and Microsoft. You can check out this feature on our public GitHub repo on our fork of TypeScript. But we're going to talk about it today as well.

So what is the motivation for this feature? Well, if you spend any amount of time on Twitter, you will definitely find people that complain about built-in performance in TypeScript. And these complaints are not unwarranted. Unfortunately, type checking can be slow, especially if you have a lot of code in a lot of projects in a model repo. So the question is, what can we do about it? Well, we could optimize the compiler, and the TypeScript team have definitely been doing that. If you check the release notes for the last several versions, you will see that every version brings new optimizations to the compiler. And that is all great work. We could also rewrite the compiler, and there's efforts out there that are trying to do this. We're excited to see where those go as well. But we tried a different approach. We thought about running things in parallel, because a lot of hardware today is multi-core, people have a lot of cores on their desktops and their laptops. And it would be great if we could take advantage of those to actually make things faster for people when they build their projects. So let's run the compiler in parallel. Let's see what performance gains we could get. What we did in Silent Bloomer, we took one of our own mono repos. It was a 23-project mono repo. It has over 100,000 lines of TypeScript code and a very deep dependency graph, so you can think something like this, lots of projects with lots of dependencies. And we tried to see what gains we could get from running the type checker in parallel for this mono repo. We took an initial baseline using TypeScript's built-in composite project support, and we got build times from about 60 seconds to 30, depending on hardware. Now, TypeScript-B, which is the composite project support in TypeScript, is actually single-threaded. It will not try to build anything in parallel, so all of these projects are type checked individually in order of their dependencies. So let's see what we could do if we try to run the compiler in parallel. What we did was we ran a separate instance of the compiler for each project.

2. Optimizing Parallelism and Dependency Management#

Short description:

We batched the projects into workers with shared caches. However, projects are not independent, so we have to wait for dependencies to finish building. This limits parallelism, allowing only a few projects to be built simultaneously.

Now, we didn't do this in a naive way. There were some optimizations that we did do. For example, we batched all of the projects into several workers, and each one of these workers had a shared file cache and a shared source file syntax tree cache, which are already optimizations that TypeScript does for its composite project support anyway. So we were just trying to emulate that.

Now, the problem we immediately ran into is that projects are not independent. So we can't just run everything in parallel. We need to actually wait for dependencies to finish building. So, for example, for the diagram I showed before of dependencies, we would get an execution that looks something like this. And we can already see that we have a great limit on parallelism and there's only two projects that run in parallel at the same time. So only two projects get type checked in parallel. And even in our sample monorepo with 23 projects, we would only get about four to build in parallel.

3. Increasing Parallelism and Isolated Modules#

Short description:

On a laptop with 12 cores, we only use some of the computing power, leaving CPU cores idle. Running things in parallel results in a 10-20% improvement, but not a dramatic one. TypeScript performs type checking, declaration emit, and JavaScript emit for each project. Unblocking a project's type checking phase requires available declarations of its dependencies. We depend on declaration emit even though it doesn't remove the need for type checking. TypeScript's isolated modules mode allows JavaScript emit without type checking dependency, making it a purely syntactic process.

Now, what does this actually mean? So, for example, on a laptop with 12 cores, which is what we see here in this picture, we only use some of that computing power. We can see that even while the build runs, there's a lot of CPU power that is still being left unutilized. A lot of CPU cores that are just sitting there idle. So, that's definitely not a great start for running things in parallel.

Let's see sometimes what kind of improvements could we get if we did this? And the answer is that we definitely will get improvements, but they're just not that great. I mean, there's about a 10-20% improvement that we get from running things in parallel using this approach, which is again better than what we had, but it's not something that is going to be dramatic.

So, how can we increase the parallelism available? How can we run more things in parallel? Well, for that, we first of all need to understand exactly what it is TypeScript actually does, and what it does is three things. It does type checking, it does declaration emit, and it does JavaScript emit. Now, these things are not perfectly independent, namely declaration emit depends on the result of type checking. But for each one of our projects, TypeScript will do all of these three things. So, inside the build for each of our projects, all of these three things have to happen.

Now, there is one key insight here, namely that what is needed to unblock a project from starting its type checking phase is that it needs to have available all of the declarations for its dependencies. So, declaration emit is what is actually needed for the dependencies. We don't really care if the dependency has finished type checking if we can get its declarations. So, the actual dependency queue would look more like this, right? Each type checking phase depends on the declaration emit of its dependencies, not necessarily the type checking. That's an interesting insight, but as long as we still have this dependency between type checking and declaration emit, the fact that this is the case, the fact that we depend on the declaration emit doesn't really help us because we need to do the type checking anyway.

Could we remove this dependency? Well, for that, we should first of all look at why JavaScript emit is so independent from type checking. How is that? We actually even have tools that do JavaScript emit without the need for a type checker. They do it completely independently of TypeScript. How is this enabled? Well, a few years back, TypeScript added a new mode to TypeScript called isolated modules. So, what exactly does isolated modules do? Well, it ensures that each file can be transpiled from TypeScript to JavaScript individually. It basically removes any dependency on type checking from JavaScript emit. So this means that JavaScript emit becomes a purely syntactic process. Tools still need to understand TypeScript syntax. So, every time we get new syntax in TypeScript, all tools that do JavaScript emit need to understand this new syntax. But the advantage is that they don't actually need to understand all the semantic rules of TypeScript. They just need to understand the syntax enough to be able to remove it. So, basically, when we do JavaScript emit, we start out with a TypeScript file, and what happens inside a JavaScript emitter is that all the type annotations are removed, right? And this is a very simple process. It's not hard to build such a transformation. At least it's not hard compared to actually building a full typechecker.

4. Cutting Dependency and Isolated Declarations#

Short description:

We can cut the dependency between declaration emit and typechecking by specifying all types in the TypeScript file. This would allow us to unblock dependencies sooner. TypeScript introduces the new feature called isolated declarations, where type annotations are added to values that make it into declaration files. The type checker is not involved in declaration emit to ensure it remains a purely syntactic transformation.

So could we use a similar approach to cut this dependency from between the declaration emit and typechecking? And for that, we have to look a little bit at what exactly declaration emit entails. So for the most part, it's also a subtractive process where we just cut things from the TypeScript file, except we're not cutting the types anymore. We're cutting the implementation. We're cutting the, for example, the initializer here, we're cutting the function body, we're cutting the constructor body. So all of these just go away in declaration files.

However, there is one exception, namely in this case, the return type of this function, because if the developer did not specify the return type, then the declaration emit needs to reach into the type checker and find out what the return type of this function will be. And this is why type checking is required for declaration emit. If everybody were to write all types in the TypeScript file, then we wouldn't actually need the type checker for declaration emit. So this is one way where we could cut the dependency if we specify all types, and this would allow us to unblock dependencies sooner.

So there are already lint rules out there that could enforce this, but it would definitely be used to have something built into the actual compile that would be a guarantee for other tools as to what annotations are necessary. So we decided to add a new flag to TypeScript that we called isolated declarations. So isolated declaration is the new feature that we are implementing. And let's have a look at what this feature would mean. So our first idea was that we should add type annotations to all values that make it into declaration files. Now, this mostly means exported values, although there are some indirect ways that values can make it into declaration files as well, even if they're not explicitly exported.

Now we did make some exceptions. In some cases, values can be trivially inferred, and maybe we can allow those without having explicit type annotations. But what is for certain is that the type checker itself cannot be involved in declaration admin, because we want declaration admin to be purely a syntactic transformation where we're just cutting out implementation, and we don't have to reach into the type checker to ask about type information from the source code.

5. Type Annotation and Inference#

Short description:

You don't have to type annotate everything unless you opt into it. If you're happy with your TypeScript builds, you can keep your project as is. Our initial thinking was to specify type annotations on everything, but that proved to be difficult for large projects. We went through three phases of inference, but encountered problems. Our code would require duplicate annotations for literals and object literals. However, we made the declaration smarter by inferring types for number and literal types, and extracting information from the parameter list for functions.

So the next logical question is, okay, do I have to type annotate everything? I mean, I want to point out that you don't have to do anything unless you opt into it. If you're happy with your TypeScript builds, if you're happy with the way TypeScript was and with your build times, you can keep your project as is. Nobody's forcing you to adopt this. If your dependencies adopt this, you won't really care because you're only consuming their declaration file, so it won't really be something that everybody has to opt into.

So our initial thinking however was that yes, we will need to specify type annotations on everything. Turns out this makes converting large projects a pain and it's not the best developer experience, especially since looking at some of these expressions, you could figure out very easily that yes, indeed, the type of something is a number. So we went through three phases. Basically, the first one was where we thought that no we wouldn't do any inference in this mode. The second one was where we thought that maybe some trivial inference is okay. And the last one, which ultimately we rejected was where we do a lot more inference. But we also ran into some problems we're going to see in a few slots. So let's see what our code would look like with each one of these versions.

So no inference. What this would mean is that you would have to specify types on absolutely everything. For example, you're assigning 20 to the variable margin. It's pretty obvious that type should be number here, but we don't allow any annotations, so you would have to specify it. You would have to specify it for this constant, basically duplicating the literal in both places, both in the type position and in the initializer. It gets even worse for things like object literals, where you have to duplicate the property names and the values, and it really becomes very painful to do so. For constants that are initialized with a function, well, you would have to copy the parameter list again to the type annotation, and also specify the return type. And again, for fields, even if you're initializing it with very basic values, that should be obvious what type they are, we would still need to specify the type explicitly.

So we decided to make our declaration a bit smarter. So if we would see a number literal, well, the type there is pretty obviously number. So you don't need to specify that. Same for literal types. For object types, it's a bit more complicated, but it's not impossible to deduce the type from the initializer. So we decided that we can support this as well. For functions that, for constants that are initialized with a function, well, you don't need to specify the whole function signature as a type annotation. We can just extract most of the information we need from the parameter list. You will, however, need to specify the return type because we don't want to have to go into the function body itself and look for any returns and try to synthesize a return type based on that.

6. Advanced Inference and Quick Fix#

Short description:

You will need to specify the return type. For fields, you can omit them if the initializer is clear. TypeScript's declaration emitter is smart, but we want to keep it dumb and fast. We can do more inference, but it may not always be right. Declarations would have to be optimistically omitted, causing problems and complexity. Adding more inferences might degrade the developer experience. To ensure easier adoption, we added a quick fix.

You will, however, need to specify the return type because we don't want to have to go into the function body itself and look for any returns and try to synthesize a return type based on that. And for function fields, and for class fields, again, you can just omit them if the initializer is clear enough for us to infer a type from.

What about if we want more, right? We were very excited by our initial success with this trivial form of inference, and we decided, well, maybe we can do more. Maybe we can infer more things. And the problem is that TypeScript's declaration emitter is very smart, and we want to keep our emitters dumb, and hopefully fast. So let's take an example. Let's say we have a variable, and we're initializing it with the value of another variable. Could we trivially infer a type for orientation? What type could we write to declaration files without having to involve the type checker? So we could try using typeOfHorizontal. This seems like a very good fit. typeOf will give us the type of the variable, and orientation should have the same type as what we're assigning, right? Well, that sometimes works.

So the answer is, can we do more inference? The answer to that is yes, but we will probably not always be right, so declarations would have to be optimistically omitted. This basically causes some problems, though, because what we're saying here is that, okay, a declaration emitter could produce declarations without the type checker, but they could be wrong. And then TypeScript itself could come back and error out looking at all of the information in the type system and say, okay, well, in this particular case, if you're using isolated declarations and you're using a standalone declaration emitter, it cannot possibly have known what the correct type is there. So this is possible, but it kind of creates a very complicated mental model, makes it very difficult to understand. Also, the errors would become much harder to understand because we would need to tell people why exactly they're erring on a certain construct. And what we ended up was errors that sounded something like, this type that is inferred in isolated declarations is different from this other type that would be inferred by TypeScript normally. And it kind of sounds like the compiler is having an argument with itself. Isolated declarations is one thing, regular TSC says another thing. And the developers involved basically nowhere in this process. So, all of this might result in actually degrading the developer experience instead of improving it, which was the reason why we wanted more inference in the first place. So definitely adding more inferences that might not always be right is not the best way to go.

So, we still wanted to make sure that people would have an easier time adopting this feature. How could we ensure that? Well, we decided to add a quick fix. The information is already present in there.

7. Improving Developer Experience#

Short description:

Adding more inferences that might not always be right is not the best way to go. To ensure easier adoption, we added a quick fix.

And the developers involved basically nowhere in this process. So, all of this might result in actually degrading the developer experience instead of improving it, which was the reason why we wanted more inference in the first place. So definitely adding more inferences that might not always be right is not the best way to go.

So, we still wanted to make sure that people would have an easier time adopting this feature. How could we ensure that? Well, we decided to add a quick fix. The information is already present in there. We just need to insert a type inside our code. Visual Studio Code already has all the information, the language service that is running in there already knows what the types of all the variables are even if they're not spelled out. So, what we could do if there's an isolation declaration we could just use a quick fix to actually insert the type without having to write it ourselves which I think is something that will definitely help all the developers adopt this feature.

8. Improving TypeScript with Isolated Declarations#

Short description:

Isolated declarations improve TypeScript in several ways. They enhance speed and unlock more parallelism by emitting declarations up front. They also improve compatibility with other tools and promote transparency by requiring developers to write types in code.

I want to send a special thanks to Hannah Jewell from Google which worked extensively on this feature and most of it is her doing.

So, how would isolated declarations improve TypeScript? Well, we hope to improve it in several ways. With this feature, first of all, we hope to improve speed, by passing the type checker to synthesize new types will probably improve declaration limit speed all on itself. We hope to unlock a lot more parallelism. If we can emit declarations up front, projects don't need to wait for the type checking phase of all of their dependencies to finish. They already have the declarations and they can just do their own type checking with that. We also hope to improve compatibility with other tools. Like I said, there are already tools out there that generate JavaScript from TypeScript. We're hoping to create a similar ecosystem of tools that could emit declaration files without the use of the type checker, but that would be 100% compatible with current TypeScript declarations. And we also hope that we will improve transparency. Developers sometimes forget to write types for their exported values. And sometimes the type checker synthesizes some things that are not particular developer friendly. There are the very large types, or types without any semantic meaning, resulting in a bad developer experience for the clients of those libraries. So if people are forced to actually write these types in code, they'll probably think more about them and the declarations will probably have a better quality just because of this.

9. Improving Performance with Isolated Declarations#

Short description:

Isolated declarations increase parallelism and improve performance dramatically. The future holds the hope of getting this feature in TypeScript soon, potentially within the next half a year. While it's uncertain if isolated declarations can help in a single project setup, there is potential for even faster performance with the possibility of an ecosystem of TypeScript declaration emitters. Special thanks to all the individuals involved in the development of this feature.

But coming back to our experiment of running the build for a monorepo in parallel, we saw that without isolated declarations, there was a limited amount of parallelism. With isolated declarations, we hope to increase the amount of available parallelism. We saw that in the other version, this was pretty limited. At most, two projects could type check in parallel in this example. What we want to do is front-load all of the declarations amid, so we can unblock all projects as quickly as possible. We want to go from this diagram to this diagram. Hopefully, the difference between these two is that time we won't need to wait for TypeScript anymore because type checking will be done much faster if we can do all this in parallel. This was the hope. Without actual numbers, theoretically this might work. But we didn't actually know what kind of performance gains we were looking at in real-life projects.

So what we did is we actually converted our sample monorepo to use isolated declarations. And we tried to see what kind of performance gain we would get from trying to build in parallel with this new approach with front-loading all of the declaration amid. So drumroll, let's look at the times. As you can see, even just by looking at the numbers, there's a great improvement there. We get even single-digit build times. Looking at a chart maybe makes it more clear the improvement in performance is quite dramatic. We're talking about three times improvement in performance. So when we saw these numbers, we were really happy that our theory sort of panned out and our expectations were actually met and even exceeded by some measures.

So what does the future hold? Well, hopefully we're going to get this feature in TypeScript soon. We don't know exactly when, but hopefully it'll happen within the next half a year. The other question I usually get when I tell people about this feature is can this help in a single project setup? We're not sure about this yet. We have done some experimentation but there are some limitations that still need to be solved in the TypeScript compiler first. We will see if we can help with that as well. Can this get even faster? We use the TypeScript compiler backbone to actually implement our own declaration emitter. There is space there for other tools to be a lot faster just as there's an ecosystem of JavaScript emitters. Hopefully, there will be an ecosystem of TypeScript declaration emitters and hopefully that will make things even faster.

I'd like to say a warm thank you to everyone who was involved from Google, Hannah Joo and Yann Kuehler, from Microsoft Daniel Rosenwasser, Jake Bailey and Ryan Kavanagh and from Bloomberg, Rob Palmer, Thomas Chatwin and Ashley Claymore. Also, a special shout out to the Flow team who implemented a very similar feature a while back and which was definitely a source of inspiration for us. Thank you very much for listening and I'm ready for any questions in the chat. Thank you.

Titian-Cornel Cernicova-Dragomir
Titian-Cornel Cernicova-Dragomir
24 min
21 Sep, 2023

Comments

Sign in or register to post your comment.

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's Most Useful Types
React Day Berlin 2023React Day Berlin 2023
21 min
React's Most Useful Types
Top Content
Watch video: React's Most Useful Types
Today's Talk focuses on React's best types and JSX. It covers the types of JSX and React components, including React.fc and React.reactnode. The discussion also explores JSX intrinsic elements and react.component props, highlighting their differences and use cases. The Talk concludes with insights on using React.componentType and passing components, as well as utilizing the react.element ref type for external libraries like React-Select.
TypeScript and React: Secrets of a Happy Marriage
React Advanced 2022React Advanced 2022
21 min
TypeScript and React: Secrets of a Happy Marriage
Top Content
React and TypeScript have a strong relationship, with TypeScript offering benefits like better type checking and contract enforcement. Failing early and failing hard is important in software development to catch errors and debug effectively. TypeScript provides early detection of errors and ensures data accuracy in components and hooks. It offers superior type safety but can become complex as the codebase grows. Using union types in props can resolve errors and address dependencies. Dynamic communication and type contracts can be achieved through generics. Understanding React's built-in types and hooks like useState and useRef is crucial for leveraging their functionality.
Making Magic: Building a TypeScript-First Framework
TypeScript Congress 2023TypeScript Congress 2023
31 min
Making Magic: Building a TypeScript-First Framework
Top Content
Daniel Rowe discusses building a TypeScript-first framework at TypeScript Congress and shares his involvement in various projects. Nuxt is a progressive framework built on Vue.js, aiming to reduce friction and distraction for developers. It leverages TypeScript for inference and aims to be the source of truth for projects. Nuxt provides type safety and extensibility through integration with TypeScript. Migrating to TypeScript offers long-term maintenance benefits and can uncover hidden bugs. Nuxt focuses on improving existing tools and finds inspiration in frameworks like TRPC.
Stop Writing Your Routes
Vue.js London 2023Vue.js London 2023
30 min
Stop Writing Your Routes
Designing APIs is a challenge, and it's important to consider the language used and different versions of the API. API ergonomics focus on ease of use and trade-offs. Routing is a misunderstood aspect of API design, and file-based routing can simplify it. Unplugging View Router provides typed routes and eliminates the need to pass routes when creating the router. Data loading and handling can be improved with data loaders and predictable routes. Handling protected routes and index and ID files are also discussed.
Full-stack & typesafe React (+Native) apps with tRPC.io
React Advanced 2021React Advanced 2021
6 min
Full-stack & typesafe React (+Native) apps with tRPC.io
Top Content
Alex introduces tRPC, a toolkit for making end-to-end type-safe APIs easily, with auto-completion of API endpoints and inferred data from backend to frontend. tRPC works the same way in React Native and can be adopted incrementally. The example showcases backend communication with a database using queries and validators, with types inferred to the frontend and data retrieval done using Prisma ORM.
How to properly handle URL slug changes in Next.js
TypeScript Congress 2022TypeScript Congress 2022
10 min
How to properly handle URL slug changes in Next.js
Top Content
This Talk explains how to handle URL slug changes in Next.js by using the getStaticPaths and getStaticProps methods. It covers implementing redirects and provides a solution to eliminate the need for editors to perform additional steps. The approach involves tracking URL slug changes and issuing proper redirects. The speaker encourages the audience to reach out with any questions or experiences with handling URL slugs.

Workshops on related topic

React, TypeScript, and TDD
React Advanced 2021React Advanced 2021
174 min
React, TypeScript, and TDD
Top Content
Featured WorkshopFree
Paul Everitt
Paul Everitt
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.
Mastering advanced concepts in TypeScript
React Summit US 2023React Summit US 2023
132 min
Mastering advanced concepts in TypeScript
Top Content
Featured WorkshopFree
Jiri Lojda
Jiri Lojda
TypeScript is not just types and interfaces. Join this workshop to master more advanced features of TypeScript that will make your code bullet-proof. We will cover conditional types and infer notation, template strings and how to map over union types and object/array properties. Each topic will be demonstrated on a sample application that was written with basic types or no types at all and we will together improve the code so you get more familiar with each feature and can bring this new knowledge directly into your projects.
You will learn:- - What are conditional types and infer notation- What are template strings- How to map over union types and object/array properties.
Deep TypeScript Tips & Tricks
Node Congress 2024Node Congress 2024
83 min
Deep TypeScript Tips & Tricks
Top Content
Featured Workshop
Josh Goldberg
Josh Goldberg
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.
Best Practices and Advanced TypeScript Tips for React Developers
React Advanced 2022React Advanced 2022
148 min
Best Practices and Advanced TypeScript Tips for React Developers
Top Content
Featured Workshop
Maurice de Beijer
Maurice de Beijer
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.
Building Your Own Custom Type System
React Summit 2024React Summit 2024
38 min
Building Your Own Custom Type System
Featured Workshop
Kunal Dubey
Kunal Dubey
I'll introduce the audience to a concept where they can have end-to-end type systems that helps ensure typesafety across the teams Such a system not only improves communication between teams but also helps teams collaborate effectively and ship way faster than they used to before. By having a custom type system, teams can also identify the errors and modify the API contracts on their IDE, which contributes to a better Developer Experience. The workshop would primarily leverage TS to showcase the concept and use tools like OpenAPI to generate the typesystem on the client side. 
Frictionless Development With Unified Type System
JSNation 2024JSNation 2024
113 min
Frictionless Development With Unified Type System
Featured Workshop
Ejiro Asiuwhu
Ejiro Asiuwhu
Imagine developing where frontend and backend sing in harmony, types dance in perfect sync, and errors become a distant memory. That's the magic of TypeScript Nirvana!
Join me on a journey to unveil the secrets of unified type definitions, the key to unlocking frictionless development. We'll dive into:
- Shared language, shared love: Define types once, share them everywhere. Consistency becomes your BFF, errors your worst nightmare (one you'll rarely see).- Effortless coding: Ditch the manual grind of type checking. TypeScript's got your back, freeing you to focus on building awesomeness.- Maintainability magic: With crystal-clear types guiding your code, maintaining it becomes a walk in the park. More time innovating, less time debugging.- Security fortress: TypeScript's type system shields your app from common vulnerabilities, making it a fortress against security threats.