This is just a naming convention for type arguments (aka generics).
Why? Type arguments are a unique kind of parameter in code (it doesn't represent a specific type or a value, rather it's a placeholder for some kind of type in that context) which is why it's useful to have some visually distinct naming pattern, for code readability.
In simple cases the name T
is often used for a type argument:
interface Collection<T> {
[index: number]: T;
}
If you have multiple type arguments it's also common to use different single letter capitals for each type argument:
class Component<P, S> {
// In React `P` represents "Props" type, and `S` represents "State" type
}
However, that can get pretty hard to read! It's well understood that single letters like T
and S
are some kind of type argument, and not specific types, but imagine some code that references P
, S
, R
, SS
, and you have to sort out what that means while you read the code. It can get hard. So for better readability you could use a full name (there's no syntactical restrictions on type argument names):
class Component<Props, State> { }
That works fine. The problem is that Props
and State
look like they could be actual concrete types named Props
and State
, but they are not. So now you have a different kind of potential confusion. So finally, to preserve readability without losing the hint that they are placeholder type arguments and not specific types, use full names prefixed with T
(for "Type argument"):
class Component<TProps, TState> { }
The only down-side to this is longer names, which is why you still see T
and such commonly used, especially in contexts where an experienced programmer is going to naturally know what that stands for, for example Collection<T>
is pretty clear, Collection<TElement>
is not necessary, and to a React developer "props" and "state" is the bread-and-butter of using React, so Component<P, S>
is going to be well known. It's still a style choice either way, in the end.
More info than you could have possibly wanted. :)