Today we're going to talk about different ways that JavaScript libraries can use and support TypeScript, how you approach migrating a JavaScript library to TypeScript, issues with dealing with the library types and versioning, and supporting multiple TypeScript versions as well, how you can debug and test types, how you approach designing APIs for use with TypeScript, and potentially some features that would make it easier for TypeScript usage with libraries. Types serve several purposes, including API documentation, user code correctness, and library code correctness. There is a distinct difference between application types and library types, with library types being more complex. JavaScript libraries can provide types by being written in TypeScript, hand-writing type definitions for JavaScript code, or using community types from Definitely Typed. The Redux libraries have used all these approaches and have been migrating to TypeScript. The first step in migration is setting up build infrastructure and configuring tests.
Today we're going to talk about different ways that JavaScript libraries can use and support TypeScript, how you approach migrating a JavaScript library to TypeScript, issues with dealing with the library types and versioning, and supporting multiple TypeScript versions as well, how you can debug and test types, how you approach designing APIs for use with TypeScript, and potentially some features that would make it easier for TypeScript usage with libraries.
So why do we even provide types with a library anyway? Types serve several purposes. One is API documentation. Users can look at the types and understand what functions and types exist and how you can use them in your application. Another is user code correctness. They can enforce certain usage patterns that users should have in their actual application source code. Along with that, there's library code correctness. Types help us ensure that the code inside our library behaves as expected, and it's about maintainability, being able to work on the actual code inside the library.
Now, I will say that I think there is a distinct difference between the types that you see inside application code and the types that you see inside library code. Application types tend to be fairly simple. You have API responses, function arguments, state that you're dealing with, component props. Usually, it's not overly complicated, and you don't see a lot of generic types in there. Library types, on the other hand, are much more complicated because they need to handle a lot more flexible use cases. Library types tend to have a much heavier use of TypeScript generics. And sometimes, you might even see type level programming where you're doing inference, conditional logic, and complex transformations of types as well.
Now, there are several ways that a JavaScript library can provide types. The best approach is if the library is actually written in TypeScript itself. This guarantees that the types match the actual behavior of what's in the source code of the library, and that the types get updated every time there's a new release of the lib. Another option is to write the source code in JavaScript and handwrite the type definitions and include them in the published output. This is okay because the types are still maintained by the actual library owners. But you can actually end up in situations where there's differences between what the types say is in the library and what the source code actually does. As a fallback, if the library maintainers don't want to have their own types, then the community can put together some types and publish them in the Microsoft-owned Definitely Typed repo. This can definitely lead to problems, but at least it gives you some way to have types, especially if the library maintainers don't want to worry about dealing with that themselves. We've really used all these different approaches with the Redux libraries over time. But we've been working on trying to migrate the Redux libraries to TypeScript, especially over the last couple of years. The Redux core actually got converted to TypeScript in 2019. We just never actually got around to publishing it. React Redux version 8 is finally converted to TypeScript, and we migrated Reselect last year. So how do you approach doing one of these migrations? Well, the first step is to get some build infrastructure set up. You need to make sure you're actually compiling the TypeScript types, transforming the build output to plain JavaScript, and you want to make sure your test setup is configured to deal with TypeScript as well.
Comments