Types Beyond TypeScript

This ad is not shown to multipass and full ticket holders
React Summit US
React Summit US 2025
November 18 - 21, 2025
New York, US & Online
The biggest React conference in the US
Learn More
In partnership with Focus Reactive
Upcoming event
React Summit US 2025
React Summit US 2025
November 18 - 21, 2025. New York, US & Online
Learn more
Bookmark
Rate this content

Everybody seems to be talking about "types" these days. From the TypeScript language to type description utilities such as prop-types and Zod, developers expect clear descriptions of the shapes of their React components, data, and hooks. Let's talk about the mindset shift that's happened over the last decade, and where types are taking us over the next one.

Brief foundations: what is TypeScript, what "type safety" means, and setting up TypeScript in a React (Next.js) projectA history of how type safety has worked in React, starting with class components

Thinking in Type(s|Script): How modeling value shapes helps raise predictability and understandability, especially in the wildest and wackiest of React architectures.

TypeScript's Limitations: By design, TypeScript can only act as a development-time type system and enforce what that system can represent. We'll want to go over what can't and/or shouldn't be represented in that type system.

Raising the Runtime: Moving those type thoughts into your React runtime with programmatic frameworks or libraries such as tRPC and Zod - especially as they integrate with React metaframeworks like Next.js and Remix.

React Specifics: How this "types-first" theory works helps improve common parts of projects in the React ecosystem: from prop-types back in the day to REST or RPC endpoints, testing, and documentation today.

ESLint lint rules to catch common async and React code bugs - and why the language is designed to let you do those dangerous things in the first place.

Ecosystem future: where the TC39 types-as-comments proposal will -and won't- take types at a language-level for JavaScript in general and React apps specifically.

By allowing our types to be a reflection of the runtime reality, we embrace types-first thinking in designing code - making our code more clear to read and update. These better-define boundaries help in everything from better-defined React component boundaries to auto-generated client<>server API bridges. Hooray, types!

This talk has been presented at React Summit 2024, check out the latest edition of this React Conference.

FAQ

TypeScript is a superset of JavaScript that adds syntax for explicit type declarations, allowing developers to specify the intent behind values in their code. This helps manage and scale code more effectively by using the TypeScript type checker to catch type-related errors.

TypeScript improves code management by allowing developers to declare the intent behind values through types. This makes the code easier to understand and maintain, especially as the number of developers working on a project increases.

Some alternatives to TypeScript include Flow from Facebook, which is more targeted towards Facebook's use cases, and Ezno, an ongoing project attempting to rewrite a TypeScript-like language in Rust. However, TypeScript remains the most popular tool in this space.

TypeScript does not exist at runtime; its type annotations are lost during the transpilation to JavaScript. It also cannot fix poor app architecture or convoluted code. Types in TypeScript are meant to describe the code rather than exist within it during execution.

Well-defined schema validation libraries, such as Zod, YUP, and ArcType, allow developers to describe a schema for validating and describing data shapes. These libraries can be used to ensure type safety, autocompletions, and better security in code.

Type-checked linting refers to linting that uses the type information provided by TypeScript to perform more powerful and accurate code analysis. This helps catch more complex issues that regular linting might miss, leading to cleaner and more reliable code.

TypeScript should not become available at runtime as it is designed to be a development-time tool. However, there are libraries like ArcType that can add runtime type checking if needed for specific use cases.

The TypeScript type cycle refers to the phases developers go through when learning TypeScript: initial excitement and overuse of advanced features, followed by disillusionment when the code becomes too complex, and finally reaching a balanced, productive use of TypeScript.

Interfaces are often preferred in TypeScript because they semantically convey that they are defining an object shape. However, both interfaces and types can be used almost interchangeably, and some features are unique to each.

The future of TypeScript includes ongoing improvements and new features. For example, TypeScript 5.5 introduces inferred type predicates from function bodies. Future versions will continue to enhance capabilities and deprecate outdated syntax slowly.

Josh Goldberg
Josh Goldberg
31 min
14 Jun, 2024

Comments

Sign in or register to post your comment.
Video Summary and Transcription
This Talk explores the concept of types and their significance in software development, particularly in relation to TypeScript. It discusses the limitations and advantages of TypeScript compared to other tools like Flow and Ezno. The Talk emphasizes the role of types in bridging system boundaries and improving code quality. It also highlights the importance of type-checked linting and the future of ESLint. Additionally, the Talk mentions the benefits of faster and easier linting with projects like Biome and OXC, and recommends books for further learning.
Available in Español: Tipos más allá de TypeScript

1. Introduction to Types and TypeScript

Short description:

I'm Josh. I'm really excited to talk to you today about Types beyond TypeScript. We're going to talk about four sections. What are types? What is this whole thing? Just in case you haven't played with TypeScript or Flow yet. Second, I want to quickly cover what types aren't. I also really want to talk about the stuff types are surprisingly good at. First, what can inform types? Like how you can set up your code to be well-typed. And then lastly, what types can inform? How having well-typed code can help tools run better on your code.

Hey, everyone! Oh, sweet Jesus. That's not good. I'm Josh. I'm really excited to talk to you today about Types beyond TypeScript. Yes. As Phil said, I do open source. Feel free to talk to me after this whole thing about that. It's a wonderful world. The ecosystem is always getting better. I work on projects. Who here uses TypeScript ESLint? Yes. Who here uses ESLint in general? Yes. Who here has sworn at ESLint or TypeScript ESLint? Yes. Who here still uses Mocha? Okay. Cool. I'm not talking about Mocha today. I'm talking about Type stuff. We're going to talk about four sections. What are types? What is this whole thing? Just in case you haven't played with TypeScript or Flow yet. Second, I want to quickly cover what types aren't. Whenever there's a new tool, as you may have seen in other recent developments in life, people get really excited and they use it for things that may or may not be good fits. And they can sometimes give the tool a bad name. I also really want to talk about the stuff types are surprisingly good at. First, what can inform types? Like how you can set up your code to be well-typed. And then lastly, what types can inform? How having well-typed code can help tools run better on your code. Really cool stuff. Are we ready for all that? Yes! Friday late afternoon at a conference.

2. Types and TypeScript in JavaScript

Short description:

What are types? In order to answer that question, we have to ask, what is TypeScript? JavaScript is a syntax along with a vague specification on how to execute this syntax. The problem with this, though, is that there's no built-in way in JavaScript to declare the intent behind those values. Which is why we have TypeScript. TypeScript adds in a syntax on top of JavaScript. It's a superset, meaning it's all of JavaScript plus this new stuff, and that syntax allows us to say explicitly not just what the values are, but the intent behind those values. It's so useful that it begs the question, why don't we have other TypeScripts? There are three examples of tools that are in the same space as TypeScript but aren't as popular as it, and I want to quickly go over. First, just curious, who here used Flow at any point in time? Flow is a lot like TypeScript. It's from Facebook, but it's actually gone a different direction from TypeScript. It's still under active development. But instead of getting a lot of usage and going worldwide and making it so everyone should ever, who has ever wanted to use types could use it, Flow is a little more targeted.

What are types? In order to answer that question, we have to ask, what is TypeScript? In order to answer that question, we have to ask, what is JavaScript? What is JavaScript? At its core, JavaScript is this. JavaScript is a syntax along with a vague specification on how to execute this syntax. This is lovely. Look at this. We have a let thingy. We didn't used to have let. Used to have var. We have the ability to assign a variable to different values. The problem with this, though, is that there's no built-in way in JavaScript to declare the intent behind those values. The intent behind those values. There's no little thing you can put there to say this is only ever going to be, say, a string. And that's problematic because code gets really hard to work with at scale. Once you pass five developers, 50 developers, 500 developers, it gets really hard to manage that stuff. Which is why we have TypeScript.

TypeScript adds in a syntax on top of JavaScript. It's a superset, meaning it's all of JavaScript plus this new stuff, and that syntax allows us to say explicitly not just what the values are, but the intent behind those values. In this case, string. Now, because we have the TypeScript syntax, we can do things like the TypeScript type checker. Fun fact, written in TypeScript, and that's a CLI or API you can call to get little complaints saying, hey, you said this was going to be a string, but you gave it a number, you silly goose. That's not allowed. You can run the type checker through the language services for TypeScript, such as VS code, great editors, and those will give you the same complaints but in little red squiggly line form, type number not assignable to string. And that's really useful. It's so useful that it begs the question, why don't we have other TypeScripts? Why is TypeScript the only tool that seems to be in popular usage today for enforcing types in JavaScript code? Not that I said popular. There are other tools, but TypeScript has the mind share. Now there are three examples of tools that are in the same space as TypeScript but aren't as popular as it, and I want to quickly go over. First, just curious, who here used Flow at any point in time? A good chunk of us. Flow is a lot like TypeScript. It's from Facebook, but it's actually gone a different direction from TypeScript. It's still under active development. But instead of getting a lot of usage and going worldwide and making it so everyone should ever, who has ever wanted to use types could use it, Flow is a little more targeted.

3. Using TypeScript for Types

Short description:

It's more for the Facebook style of use cases. TypeScript is written in TypeScript. It executes at JavaScript speeds. Ezno is an ongoing project attempting to rewrite a version of a language similar to TypeScript in Rust, but it's taking a while. We're kind of stuck with TypeScript right now, for better or for worse. This talk is about types. TypeScript just so happens to be the implementation detail of how we're writing and using them.

It's more for the Facebook style of use cases. It's diverged a bit which means it's dropped off in popularity compared to TypeScript. Now I mentioned that TypeScript is written in TypeScript. That means it executes at JavaScript speeds. It would sure be nice if we could execute at Rust speeds, at native code speeds, which is what the STC project was, but that project was abandoned because it turns out it's really hard to reimplement TypeScript in a new language. Ezno is an ongoing project attempting to rewrite a version of a language similar to TypeScript in Rust, but it's taking a while. So between Flow being all hipster, STC being abandoned, and Flow, pardon me, Ezno being in progress, we're kind of stuck with TypeScript right now, for better or for worse. Which means this talk is really just types. I'm talking to you about types, and it's a coincidence that I happen to be using TypeScript for that. But I really want to hone in on that. This talk is about types. TypeScript just so happens to be the implementation detail of how we're writing and using them.

4. Types and TypeScript: Bridging System Boundaries

Short description:

Types and TypeScript are like information glue that merges different system boundaries or parts of your app. TypeScript helps bridge the gap between components by providing autocomplete and type definitions. Well-typed systems can be better understood. Function components in TypeScript are much easier to statically type compared to class components. TypeScript offers powerful features like generics, mapped types, conditional logic, extreme inference, and the ability to implement binary arithmetic in the type system. But remember, don't use TypeScript for everything!

Okay! New talk? Types? Yes. All right. All right. Let's think about types and TypeScripts. First of all, why do we like them? I like to think of them as an information glue that helps merge together or a bridge that helps bridge together different system boundaries or parts of your app. Suppose you have a new component. You've got that blinking cursor. What the hell are you supposed to do with this thing? Read the source? No, you would typically use the TypeScript autocomplete or the type definitions, the little drop-downs in your editor, to figure out, ah, someone wrote that there's some props for this component. That's really useful. And then if you get it wrong, TypeScript helps, it informs you, hey, you're trying to bridge that gap, but it's a pedestrian-only road and you're riding a bike. That's not allowed. So I want to really emphasize for that, the better typed your system is, the better your tooling can help you use it. Well-typed systems can be understood better.

Back in the day, does anyone remember writing class components in React? That was big for a while. A lot of us. This is how you used to write things. This is a lot of code. Classes are also actually really hard to statically type because a lot of the time methods other than the constructor might modify your state and then you have this weird case where other methods don't know. It's a nightmare. Even the code, it's, oh, my God, look at this! But now we have function components which are much easier to statically type. There's a reason why solid.js hasn't gone back to class components. And once you start writing things in TypeScript, you get this beautiful generic thing. You realise, oh, my gosh, TypeScript is actually really powerful. There's a lot of cool stuff you can do in the type system. You can do generics that reference other generics or specifically type parameters. You can have mapped types which map from one type to another. You can have conditional logic in the Turing complete type system. You can have extreme inference in your logic. You can implement binary arithmetic in the type system. You can use TypeScript for everything! Please don't do that.

5. TypeScript: The Type Cycle and Runtime Existence

Short description:

TypeScript type cycle: peak of inflated types, disillusionment, and plateau of type productivity. TypeScript does not cure convoluted code or fix app architecture. Prefer simpler code resulting in simpler types. TypeScript does not exist at runtime. Proposal to add types to JavaScript as comments.

Do not go down that path. I understand yesterday there was a mention of the Gartner hype cycle. I like to refer to the TypeScript type cycle. Every developer who goes deep into TypeScript goes through this. You go through this peak of inflated types where you realise, oh, my gosh, the type system has logic, I can do everything in it. And then you overuse that and your team-mates have no idea what the heck your code is doing. So you then get disillusioned, and you then realise you don't know what the heck your code is doing in the type system. So you stop doing that, hopefully.

And then once you figure out the plateau of type productivity, when you're using TypeScript just the way it's meant to be used, and not overusing it, that's when you're most efficient. That's a good place to be. So that brings us to the second of four cases, what types aren't, or what TypeScript isn't in this case. TypeScript does not cure your convoluted code. TypeScript does not fix your app architecture. If you're writing incomprehensible, unreadable garbage, TypeScript can only band-aid on top of it. If you have complex ideas, the types describing those ideas will then likely have to be complex. So it's good to prefer simpler code resulting in simpler types. Pro-tip!

Also TypeScript does not exist at runtime. TypeScript is not a runtime helper. Types do not exist. When they get transpiled from TypeScript to JavaScript, your code areas just lose all those type annotations. Something like this does not work because interface some shape does not exist at runtime. The compiled JavaScript just doesn't have it, so you're referencing something that doesn't exist. Don't do that. No types for you. I do want to mention there is actually a proposal to add, quote, types to JavaScript, but it's just a new syntax for them. It's a space to put comments describing the types. Though this is a very exciting proposal, it's just comments. It doesn't actually capture all of what TypeScript is, so for a while, you would still need TypeScript as they iterate on it, and it's years away from early testing. Years and years.

6. The Zen of Types and Schema Validation

Short description:

Adding types to JavaScript is controversial. Types should describe values. Schema validation libraries like Zod provide TypeScript parity and inference. Use Zod for data with shared, validated shapes.

Years and years. It turns out adding types to JavaScript is a somewhat controversial proposal, so it's going to be locked in committee for a long time. Oh, well. The reason why I'm really excited to talk to you about not using types for certain things is because types are not the root source of everything. Oftentimes, in your code, it's best that your types are just a description of or a by-product from your values. You write your code, and then the types describe how that code is meant to be. So no runtime types, I'm going to instead dive into the zen of types here. How do we go from really nicely described code, or really clear values, to really nice, clear, well-described types? In other words, how do we inform our types nicely?

The first thing I want to show is schema validation libraries, part three of four. Well-defined schema validation libraries, out of curiosity, who here has used one like YUP or Zod or ArcType? All great options. A lot of but not all of the room. Let's talk about this. Back in the day, we had this old thing in React called PropTypes used to be built into React and separated out. That was a very early way to describe a schema to validate and describe the props, the stuff that went into your components. Which is awesome. It was kind of straightforward, like, this code is pretty readable. It's understandable, I get what it's doing, but it wasn't fully TypeScript feature-complete, it didn't map to all the features one might want in the type system, and, as a result, the TypeScript inference story was never really fleshed out. You ended up with a lot of companies that would just write everything twice. We don't like that.

So instead, now, we have, well, often times, a new round of schema validation libraries like the ever-popular Zod. This is pretty similar-looking code, but the interesting thing is we have a separate schema, box schema, and then a built-in Zod helper called infer that takes in the box schema's type, the type of, and gives back an interface or a type. In addition to being straightforward usage and understandable syntax, we also get TypeScript parity and we get TypeScript inference. So that's really nice. Now, I'm not saying you should use Zod schemas for all your component prop types. If you're not validating your props, there's no need for that. But if you are using data, shared, usable, validated shapes, this is quite nice. So this is just an example of how Zod might look in a more complex app. Zod supports unions, which are types that represent values that can be one or more possible things, represents objects, optionals, all sorts of great stuff. One example of how you might use it would be if you have some unknown data and you want to render in a component, well, you could try parsing or safe parsing it with Zod, and if that's succeeded, you render the component box, or if not, you render some error. Notice how I'm not really doing a lot in TypeScript here. I'm describing the Z.infer, I'm describing what the props are, but my values are describing the logic, the flow, the if not parsed.success then do this thing, from values come types.

7. Shared Schemas and Code Generation

Short description:

Shared reusable schemas improve type safety, autocompletions, and security. TRPC is a recommended approach for type-safe server-client interaction. GraphQL and open API (Swagger) are alternative approaches. Well-typed code can generate SDKs in different languages.

And what is also really interesting is once you have these shared reusable schemas, you can share between client and server. You can have the schema in the bundle on the client that describes the type you would send to a network request, and then you could also have the schema used in your code on the server to validate that the network request was sent to you successfully. That means you have better type safety, autocompletions, you have better security because I don't know how many of you have had to manually validate that request params are valid because you had a hacker one report, about a 500, but it is a nightmare, this is a much better way. And by doing so, you get this kind of symmetrical beauty between your client and server where you have the shared schema that helps both of them.

So there are actually quite a few different ways to do what I just described. The closest to what you just saw that I really recommend trying out first is called TRPC. Type safe what is it? What does RPC stand for? Thanks! I didn't hear anything! On your server, you can define your Zod schema and then a query thing, if someone gives you options with an input, you return a string. Notice the as constant there, that tells TypeScript to use that literal string type which you will see in the next slide. Once you have that on your server, you can also have it linked with the client. There is a little bit of skeleton backbone code here, but notice the last few lines on the right, await TRPC.greeting.query, name Attila, and the type of that variable is HiAttila, who by the way was the photo you saw earlier of the guy with the serious face.

Another interesting approach is GraphQL which is nowadays a little older but still good in large use cases. There are different ways to do it. One would be having a GQL or GraphQL file describing the GraphQL syntax for a type, and then some queries somewhere, maybe in a query file. I think I used the wrong extension on this slide. You can auto-generate types from those, from your schema and your queries. It is really useful. The last one of the three is open API aka Swagger. I have yet to determine which term is still in use in which context, but you can define a schema file, say in YAML, and auto-generate your code from that schema file. This is a small example. I've seen very big complex, in a good way, lots of features, SDKs generated from schema files. Alternately, you can go the other way. You can use well-typed code to be statically analysed by Codegen to create your schema file directly from your code. From your server, say, which means you can generate SDKs in different languages from your server. How ridiculous is this? We started off with a TypeScript server and now we are auto-generating SDKs in Python and Rust based off of that. Who here writes the SDK manually at a company that has multiple languages of SDKs? Oh, four of our hands. I expected it to be more. Clearly, you're all using open API. This is great. The better typed your system, the better your tooling can help it. The better typed your system, the better your tooling can analyse it.

8. Type-Checked Linting

Short description:

Type-checked linting is a powerful tool for improving code quality. Linting, type-checking, and formatters are three forms of static analysis. Linters can teach new syntax and provide language-specific insights. Type-aware lint rules leverage the power of TypeScript to enforce best practices and optimize code execution.

What types can inform once they are well typed, well described is our last section, and I'm most excited about this one because I'm going to talk about what I work on day to day, type-checked linting!

Who here uses type-checked or type-aware linting? Wow! Actually, a good number. Thank you. That is awesome.

First of all, you should probably lint your TypeScript code. I can't say for sure, maybe you're not a lint-happy person, but if types are justified at your scale of application, linting is probably too. There are three forms of static analysis. Linting does not mean type-checking. There are formatters, like prettier, which just format your code, they don't change logic. That means they are in a good way dumb, very quick. Then there are type-checkers which are very powerful but slower, aka TypeScript. And then there are linters, like ESlint.

Now, linters are great. As an example, they can teach you new syntax. There's a built-in ESlint rule, logical assignment operators which would look at this code and say, fun fact, there is a new JavaScript feature that can write slightly cleaner code for you. Look at that. How nice. We learned something. You seem smart. And they can also teach language or framework or library-specific things. TypeScript ESlint would let you know, wait a second, that name, hi, Daria, there's actually a nice as-const feature you can use to do that same thing. Awesome. But that's just looking at the raw syntax. And once we have types, once we have an awareness of not just the one file we are looking at, but the entire project, we can write much more powerful lint rules. We can make this almost new classification of lint rules, like type-aware or type-check lint rules that tap into the power of TypeScript.

For example, you could look at this code, and because you have a type system behind you, you could say I know for a fact console.log is supposed to return void, nothing, not a thing to be used, which means the TypeScript ESlint await-venable rule could say you awaited a non-promise or by the spec non-venable value, something without a ven, that's unnecessary, that just wastes a tick in your program execution, so we could suggest you remove that.

Now, that example is not very exciting. I realize none of you have written await console.log, so let's look at something more exciting, some React code that I'm not going to give you enough time to read, but I will tell you that this has an onclick that's a function, and somewhere inside a handler that's supposed to set a running state to true, we await onclick. After that, we set running false. With the same lint rule, we could say hang on a second, onclick returns void, not promise, so the lint rule would tell us for this one I don't think you need to do that. So we could remove the onclick, or we could change the onclick to return promise void.

9. Type-Checked Linting Recap

Short description:

If our code is supposed to return a promise, we can remove unnecessary code with linting. Types are information glue that help define system boundaries. TypeScript is not a runtime thing, it only exists during development. Well-defined schemas and type linting are recommended. TypeScript is supported by popular frameworks and ESLint has released a beta of types in ESLint V8 with great features.

If our code is supposed to return a promise, great, that works, but what if we never actually used that async behaviour? What if the await was supposed to be removed, because then if the await was supposed to be removed, we could see that we have two React set states, equivalents, those run synchronously, so we can remove them. Since we can remove them, the whole onclick and disable function is unnecessary, so we can remove that, which means the button disabled equals running, button disabled equals false, which means we can just say button, we don't need disabled, which means we've removed a third of our code with linting! Yes! Woo! Hell, yeah! Thanks for the lighting! Amazing. I highly recommend, I will show resources and references after this, use type-checked linting for a better informed, more powerful set of lint rules. It's a good time. So I'm almost out of time, I will just recap, I will go quick, these are photo capable slides if you want. First of all, what are types? Types are information glue, they help define system or component or area boundaries. They're great. Type script type cycle, please try to control yourself when you're first getting into it and learning all the advanced stuff. Type script isn't a runtime thing, it only exists during development. Values two types. The Zen area. Well-defined schemas are useful. Types can inform tooling but I recommend trying out type linting at the very least. If you want to get started, all the frameworks used in the framework authors and the first two rows support type script by default. We have great docs and ESLint and we just released a beta of types in ESLint V8 which has all sorts of great features, it is ESLint V9 support, which I know everyone is really annoyed at us not having yet, sorry, and it has a new way to configure type linting which is 10 to 20 per cent faster, significantly easier to configure and more fully featured. So that's all I have. Thank you very much, everyone.

10. Types versus Interfaces and TypeScript Versions

Short description:

Types versus interfaces in TypeScript. Most of the time it does not matter which one you use. Personally, I prefer interfaces whenever possible. TypeScript 6.0 and 5.5 have exciting features. The new 'is assignable to' API will make writing powerful lint rules easier. Deprecating old syntax is also happening gradually.

The top question that has come in has been voted by many people. I'm sure you have been asked it before. Do you have an opinion? Types versus interfaces. Types versus interfaces. Oh, my gosh, what a question! It wasn't you, Attila? Most of the time it does not matter whether you use types or interfaces, the two are almost equivalent in TypeScript. They're both things that can define an object shape. I personally recommend just use the TypeScript ESLint rule that consists in type definitions that has you choose one or the other. Personally I prefer interfaces whenever possible because that's semantically what you're trying to convey. Type is kind of a coincidental copy and paste in terms of the TypeScript semantics. But if you're the type of person who is like I just use type for everything, jolly, good for you. That's fine too. There are some things you can only do with interfaces and some things you can only do with types which is really annoying. Should there be one unified thing? It's just how the language evolved over time. We can't change it.

I say we can't change it, but my next question is whether you have any insight into the future, any ideas on what might be coming in TypeScript 6. You know, every once in a while I have a conversation with someone who seems to think I'm on the TypeScript team. So just to be safe, I'm not on the TypeScript team. I have contributed in the past as an external person, but it's been a while. TypeScript 6.0 is going to have some awesome stuff. But even before then TypeScript 5.5 is about to go stable. You have the release candidate and beta out. And oh my gosh, 5.5 has these awesome features where type predicates can be inferred from function bodies. If you don't know what that is, that's awesome, just go read the release notes. They're fantastic. If you do know what that is, you know how awesome that is. Is there anything you'd want to see in TypeScript 6.0 or 5.6 or whatever? There's a new API that's recently been made available called is assignable to. That's going to make it a lot easier to write really powerful typed lint rules that I'm really excited about. Also they're deprecating a bunch of old syntax very slowly over time which is also very exciting. That's awesome, yeah. Yes, good.

11. TypeScript Limitations and Future of ESLint

Short description:

TypeScript's limitations are both broad and specific. TypeScript itself does not recommend a specific approach, be it classes or functional programming. However, there are valid use cases for classes, such as small data packages or extending the error class. The future of ESLint compared to new Rust-based tools like OXC, Biome, and Dinolint is exciting. Currently, TypeScript ESLint is the leading linter with typed linting, but the landscape may change in the future.

I like slow deprecations. Very, very, overly slow. Overly slow. That's not a question. I feel like you covered a bit of this, but if there's anything you want to go deeper into, what are TypeScript's limitations? It's hard to answer that because there are broad answers that I already gave and then there are specific answers. So I'll answer that in person if you're interested.

Okay. There's Q&A in the booths over at the back there. Come talk to me. I'm very friendly. Okay. In that case, how do you feel about classes in TypeScript and or JavaScript? We're using, I guess, class syntax. Is that something you recommend or? TypeScript itself does not recommend either class approach or functional approach. It doesn't recommend OOP versus FP versus whatever. TypeScript just describes your code. Classes the way folks have traditionally interpreted solid principles and object-oriented programming actually really violate solid and OOP. So I'd say the way that you're writing classes in Java is probably awful. Only relatively newer Java practices have made me not unhappy. There are a lot of valid use cases for classes.

For example, small data packages that have a bunch of private helpers or extending the error class. So there are uses for classes. I personally don't often use them. Fair enough. Okay. Where are we going with this? Boom. What is the future of ESLint compared to new Rust-based tools like OXC? OXC, Biome, Dinolint? Very excited about that. I was also excited to see other speakers touch on this shared AST stuff like Evan yesterday and Anthony. There is not a single mainstream linter out there that can completely compete with TypeScript ESLint now. We have typed linting and no mainstream linter such as Biome or OXC does. However, that is not going to be the case forever.

QnA

Faster and Easier Linting with Biome and OXC

Short description:

Projects like Biome and OXC offer significantly faster and easier to configure linting. Another project, TSSlint, is also working in this space. Favorite ESLint rules include no floating promises and rules that enforce good promise usage. Additionally, there is a deprecation rule that helps identify the use of deprecated APIs in TypeScript. As for book recommendations, the speaker suggests their own book.

I would highly encourage anyone interested in significantly faster or easier to configure linting to go look at and even contribute to projects like Biome and OXC. They're filled with really, really nice people and I'm excited about it. There is also another project called TSSlint, which is also working in this space. Not to be confused with TSLint, which is the old deprecated thing that predated TypeScript ESLint that I helped kill. Great. But yeah. They're very good. They're very fast. A lot easier to configure. At the cost of they're still newer, so they're still getting feature parity. They're newer, so they can move faster as well, which is really cool, I guess. Yeah. Get involved. If you want to see it, get involved. Yeah, for sure. Love that.

Do you have any favorite ESLint rules? Favorite ESLint rules? Oh my gosh! Yes. No floating promises. Which says if you create a promise, then don't just let it float away. Make sure something like try-catches it or stores it in a variable or passes it to a function. We're actually adding a bunch of features to that rule because I know it's kind of hard to work with sometimes. That await venerable no misused promises. There are a whole bunch of TypeScript ESLint rules that help enforce good promise usage to avoid async await shenanigans, which I really like. Also there's a deprecation rule, which is awesome, which just lets you know if you're using deprecated APIs in TypeScript, which is bizarrely helpful in enterprise. Any deprecation rules, yeah. Also... Move into the modern stuff. Yeah.

Do you have any good TypeScript book recommendations? Any good TypeScript book recommendations? Yes. Obviously mine is great.

TypeScript Books and Component Syntax

Short description:

The second edition of effective TypeScript, authored by Dan Van Der Kam, is highly recommended. Stephan Baumgartner's TypeScript cookbook provides practical hands-on solutions. TypeScript should not add run-time types, but libraries like ArcType can be used for specific use cases. TypeScript does not currently support component syntax and render types, unlike Flow.

Blah, blah, blah. But effective TypeScript edition 2 just... Yeah, second edition just came out from Dan Van Der Kam who authored the type predicates feature in TypeScript 5.5. It's an excellent read. I like it as, among other uses, a sequel to learning TypeScript. It really dives in and explains really a lot of best practices and things to avoid all over the place, along with why those are the case. Cannot recommend effective TypeScript enough.

If I can jump in as well, I read Stephan Baumgartner's TypeScript cookbook. Yes, the TypeScript cookbook. And that is full of very practical hands-on using TypeScript and problems that you may come across and solve. So I really liked that as well. Yeah. The cookbook's great.

You talked about the type comments in JavaScript, but should TypeScript become available at run time? Yeah. At run time TypeScript? TypeScript should never add run time types. That's not something we should or could build into a typed superset of JavaScript. That is supposed to be used the way TypeScript is. However, there are a lot of libraries you can use to add those in, if that fits your specific use case. I would encourage you to check out ArcType. It's a really cool library from David Blass over in Boston, where I'm moving in August. Woo! And it does a lot of really cool type shenanigans. Nice.

OK. Will? This is another, Will, TypeScript has support for things you may or may not know. Do you think TypeScript will add support for component syntax and render types? Apparently Flow has it. Yeah. Actually, plugging to Flow, Flow has this awesome component syntax that makes it easier to declare React function components and similar. We're not getting it in TypeScript until it lands in JavaScript, because TypeScript no longer adds new run time things, and that's kind of bordering on that. It's a different syntax than JavaScript, which TypeScript is afraid to do.

TypeScript Syntax, Type Theory, and ESLint

Short description:

TypeScript is afraid to introduce a different syntax than JavaScript. When discussing type theory with colleagues, find a suitable context to avoid conflict. Timeboxing arguments and picking a type solution can help. ESLint and linters are not good at formatting, while Biome improves the experience. ESLint TypeScript does not replace TSC, and TSC should be used for TypeScript type check errors.

It's a different syntax than JavaScript, which TypeScript is afraid to do. They don't want a conflict. So yeah, if it lands in JavaScript, which I really doubt would happen in the next decade, but you never know, then we do. Wonderful.

Aside from giving talks at conferences, how do you avoid going into lengthy type theory discussions whilst arguing with colleagues about TypeScript? Well first of all, I quit my job. So I don't have colleagues! No colleagues! But when I did... Flawless. There's a time and place for these. If you're having a lengthy type discussion, that should be in a context and situation where you feel comfortable and they feel comfortable. Screaming at each other in a team meeting or over a pull request is not good. By the time something hits pull request, you should have a shared expectation of what types to use. Sometimes it just doesn't matter. Pick one and go with it. That's an esoteric topic for most people. Timebox the argument. Timebox. Cool.

You have opinions on this, I believe. Should ESLint also be responsible for code formatting? I had a really good conversation with Anthony Foo, I think three times now we've had the same conversation. From an implementation side, ESLint and Prettier or linters and formatters are very different. And ESLint and linters are not good at formatting. They structurally are not good at it. However, it's a pain in the butt having two different tools, which is part of why everyone is so excited about Biome, because Biome makes this a much better experience. So, fundamentally, I don't believe so, but I recognize why the ESLint stylistic project, which lets you use ESLint as a formatter, it's a lot of stylistic rules, is really nice. So, eh.

Does ESLint TypeScript make running TSC unnecessary? It's a great question. It does not make TSC unnecessary. I keep forgetting to look up if there's a plug-in that surfaces TypeScript diagnostics, which are the outputs, the squigglies, but no, we do not surface TypeScript type check errors. That's just not what we do. That's what TSC does. All right. Well, that is all the time we have for questions. Give it up once more for Josh. Thank you so much. Thanks, everyone. Thanks, Phil. That was great.

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
Top Content
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.
Faster TypeScript builds with --isolatedDeclarations
TypeScript Congress 2023TypeScript Congress 2023
24 min
Faster TypeScript builds with --isolatedDeclarations
Top Content
This talk discusses the performance issues in TypeScript builds and introduces a new feature called isolated declarations. By running the compiler in parallel and using isolated modules, significant performance gains can be achieved. Isolated declarations improve build speed, compatibility with other tools, and require developers to write types in code. This feature has the potential to further increase performance and may be available in TypeScript soon.
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.

Workshops on related topic

React, TypeScript, and TDD
React Advanced 2021React Advanced 2021
174 min
React, TypeScript, and TDD
Top Content
Featured Workshop
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.
Practice TypeScript Techniques Building React Server Components App
TypeScript Congress 2023TypeScript Congress 2023
131 min
Practice TypeScript Techniques Building React Server Components App
Workshop
Maurice de Beijer
Maurice de Beijer
In this hands-on workshop, Maurice will personally guide you through a series of exercises designed to empower you with a deep understanding of React Server Components and the power of TypeScript. Discover how to optimize your applications, improve performance, and unlock new possibilities.
 
During the workshop, you will:
- Maximize code maintainability and scalability with advanced TypeScript practices
- Unleash the performance benefits of React Server Components, surpassing traditional approaches
- Turbocharge your TypeScript with the power of Mapped Types
- Make your TypeScript types more secure with Opaque Types
- Explore the power of Template Literal Types when using Mapped Types
 
Maurice will virtually be by your side, offering comprehensive guidance and answering your questions as you navigate each exercise. By the end of the workshop, you'll have mastered React Server Components, armed with a newfound arsenal of TypeScript knowledge to supercharge your React applications.
 
Don't miss this opportunity to elevate your React expertise to new heights. Join our workshop and unlock the potential of React Server Components with TypeScript. Your apps will thank you.
Advanced TypeScript types for fun and reliability
TypeScript Congress 2022TypeScript Congress 2022
116 min
Advanced TypeScript types for fun and reliability
Workshop
Maurice de Beijer
Maurice de Beijer
If you're looking to get the most out of TypeScript, this workshop is for you! In this interactive workshop, we will explore the use of advanced types to improve the safety and predictability of your TypeScript code. You will learn when to use types like unknown or never. We will explore the use of type predicates, guards and exhaustive checking to make your TypeScript code more reliable both at compile and run-time. 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.
Are you familiar with the basics of TypeScript and want to dive deeper? Then please join me with your laptop in this advanced and interactive workshop to learn all these topics and more.
You can find the slides, with links, here: http://theproblemsolver.nl/docs/ts-advanced-workshop.pdf
And the repository we will be using is here: https://github.com/mauricedb/ts-advanced