TypesScript 1.8 introduced the concept of type parameters as constraints, also known as F-Bounded Polymorphism.
But what does type parameters as constraints really mean? To answer that question we first need to understand what a type parameter is.
What is a Type Parameter?
A Type Parameter is a placeholder for a type. They're used with generics and allow you to defer the decision of choosing a type. The actual type is provided when the generic type is used.
Consider the following custom type that uses a type parameter:
type myType<T> = T;
Here we've defined a new type called myType
that uses a type parameter called T
. When we use this type we will define what the type parameter T
represents.
let count: myType<number>;
count = 1; // This is OK.
count = ''; // Error, number expected
In the above code we create a new count
variable of type myType<number>
. Comparing the usage of myType
to it's definition, we can see that we've specified that the generic type T
is number
. This means the type of count
is number, because that's exactly what our myType
defined:
type myType<T> = T;
When we passed number
we basically wrote:
type myType<number> = number
Which basically boils down to:
type myType = number
which is the same as using the number
type directly.
Type Parameters as Constraints
Now we know what a type parameter is we can use this knowledge to help us understand what type parameters as constraints actually means.
From my understanding, this simply means that the type parameter can be used a type parameter constraint, that is, it can be used to constrain the type passed in as a parameter to the same type as the type parameter. This is easier to understand with a code snippet:
type funcType<T> = (a: T) => T;
The above snippet defines a new function type called funcType
. This type utilises the type parameters as constraints feature - it constrains the type of the argument a
to the type of T
. If T
is a number, then argument a
must be a number too.
const myFunc: funcType<number> = a => a;
myFunc(1) // This is OK.
myFunc(true) // Error, expected number.
Conclusion
The term type parameters as constraints wasn't intuitive to me. I wrote this article to help me understand what this term actually means. As we discovered, type parameters as constraints basically means we can constrain the type of a function argument to the same type as the provided type parameter. As long as you understand that a type parameter is used to defer the decision of a type for generics, the description previously provided should make sense.