Hey there, everyone. I'm excited to talk about the potential of higher kinda types for library semantics today, as part of the TypeScript Congress 2023 lightning talk. First, a little bit about myself. My name's Michael Potit. I'm an engineering manager at Volley, where we are creating the future of voice-enabled entertainment. I have a passion for type-level programming. I've created HKT Toolbelt, which we'll mention a little bit later. You can read about my programming on my blog at code.lol. And I'm excited to talk about the flexibility of higher kinda types in TypeScript today.
So, library semantics. What do we mean by this? So, we want the type system to infer as much about our code as possible. Often, libraries don't do it. So, in this code example, we're using Lodash. We are doing a chain on some sort of object. We're calculating the keys, and then we're mapping those keys to convert them all to uppercase. What we know the value to be is A, B, and C in uppercase, but Lodash just infers an array of strings. So, this is sometimes very inconvenient, and forces us to make explicit type declarations when we otherwise would not have to. So, HKTs basically make better inference possible. We can use HKTs to represent type level operations, and we can compose types together using functional semantics. We can do this so well that end users never have to write any sort of custom types themselves.
So, what are higher kind of types? Basically, a kind is a type associated with a type constructor. In TypeScript, you would know this as like type foo of T equals T, right? The simplest kind is just star, these are your base types. And the next simplest kind is star to star, which is your normal sort of one-erity generic. So, like, capitalize of S or promise of T, etc. So, TypeScript natively supports these two, but we want more. So, we would like to support, for example, a type that takes in a type, sort of generic itself, and a value which represents an array, and we want to loop over that array applying this type operation to each element. So, the kind associated with this would be this sort of complicated expression, which we need to do clever things to support in the TypeScript system. So, what are we actually trying to do? So, what we want to do is we want to write code like this, so we want to say we want to use this operator, or any sort of application operator, and say, oh, right. We want to apply the operation capitalize to map, so that we get map capitalize, which, you know, converts capitalize into something that can be mapped over an array, and then we want to apply that to an array to get a result. So, we're extracting out the logic intrinsic to looping over an array and applying a transformation to each element.
Comments