Check out a free preview of the full Intermediate TypeScript, v2 course:
The "infer Constraints" Lesson is part of the full, Intermediate TypeScript, v2 course featured in this preview video. Here's what you'd learn in this lesson:

Mike discusses the TypeScript 5 feature of applying constraints to inferred type parameters and provides examples of using the "infer" keyword to extract specific types from tuples. How to express conditions and constraints on inferred type parameters, questions about rest arguments, and the use of underscores as placeholders are also covered in this segment.

Get Unlimited Access Now

Transcript from the "infer Constraints" Lesson

[00:00:00]
>> Let's talk about constraints that we can apply to infer. So, this is a new TypeScript 5 feature. And what we can see here is an example where we're saying, I want to get the first stringish element of a tuple. Let's look at these examples. So in the case of type 1, These are just our test tuples, so we get success, we get the number 4.

[00:00:39] That seems good. What we can also do here is say, infer S extends string. And in terms of the pragmatic use case for this, so you see here for t2 we get never now. I've been describing this S as a type parameter we're declaring on the fly, right?

[00:01:18] Once we match the condition, we sort of can point to a particular place where a type parameter would go and we can extract it out. We're creating a new type parameter on the fly. Just as we want to be able to state constraints like this, on type parameters that are declared up front, sometimes you wish to do the same on inferred type parameters.

[00:01:42] You don't wanna just take whatever you can get. You wanna be able to say, this needs to be met. It ends up becoming part of the condition, right? So it's almost like you're saying this, String, So we'll observe, in the first case, it'll be string, right? We're not actually teasing out the string literal type anymore.

[00:02:09] This should be never, and it is never. So, if we're type-checking for this, we don't need a constraint on the inferred type param. Could be anything, we'll take it. If this is really the way we wanna describe our condition and we just wanna grab this whatever it is, it could be literally any type, then we don't need a constraint.

[00:02:35] But as soon as you're saying, look, this is what I really wanna express my condition S, I wanna express it like this. But if there's a more specific thing, like if there's a string literal type here, I wanna extract that out and I wanna be handed it. That's where you have to say, infer S, and there's a minimum requirement that S is a subtype of string.

[00:03:01] It could be string itself, but it could be a much more specific, like a single string literal, or a union of many string literals, or even strings that begin with a, b, c, there's a way to describe that. A very good question from the chat, Mahmoud asks, what is this?

[00:03:28] [LAUGH] It's a rest argument or it's a spread param, if you wanna think of it that way. What we're saying is there could be any number of other elements in this array-like thing. I don't care what their types are, there can be as many as you want. And just as a convention, sometimes we use underscores to represent things that we are going to ignore.

[00:04:00] I could just as easily do this. Something like that. But underscore is sort of a shorthand in some languages, where it just means it's here but I am not gonna reach for it, I don't need it. Some languages will even prevent you from accessing that, where you're saying, by writing underscore here, you're saying, you're not going to use that, and you may not.

[00:04:35] And if you wish to, give it a name Sorry, that's a little curveball syntax there, [LAUGH] I shouldn't left that in. Yep, LJ says Go acts like that, a language I've used before, Elixir also acts like that. So it is something you'll see elsewhere.