What are the general rules that dictate when, where, how and why angle brackets, i.e. "<...>"
, should be used in TypeScript?
While I think I understand many individual uses of these brackets, I have a hard time seeing general patterns for their use: They sometimes seem to be prepended before things, sometimes appended after things; sometimes they are used for generics, sometimes for specific types; sometimes they appear where I might have naively expected the colon syntax to be used.
I have a reasonably good understanding of TypeScript basics: In general, I've studied the TypeScript home page tutorials, gone over significant portions of the TypeScript spec, read the "Definitive TypeScript Guide" web site, and followed a "Mastering TypeScript" video tutorial. On this particular topic, I've also searched Google and StackOverflow.
My issue isn't so much understanding any one particular use of angle brackets. Rather, I'd like to have a concise but exhaustive/universal explanation of what the brackets mean, their exact syntax, when they should be used, when they shouldn't be used, etc.
UPDATE:
I am updating my question in response to some comments in order to clarify why I'm asking this question and what exactly I'm looking for.
Let me illustrate my request by giving an example of something I do know the general rules for: curly braces in vanilla JavaScript. Curly braces always come in a pair of an opening and closing brace which surround an entity. That entity can be one of two main 'things'.
First, curly braces can surround a grouping of statements in:
the body of a function, method, constructor, or generator,
the body an if
statement/clause or else
clause,
the body of a for
, for
/of
, for
/in
, while
or do
/while
loop,
the body of a try
, catch
or finally
block, or
an anonymous block of statements.
Second, curly braces can also surround a list of:
properties of an object literal,
constructors, properties, and/or methods of a class
declaration,
functions and/or constants to be export
ed or import
ed from a module,
case
s following a switch
criterion, or
enum
s.
(Whether or not this list is complete and/or correct is not the point.)
Now imagine someone learning JavaScript. So far, she might have learned correctly how to use curly braces to surround a block of statements, i.e. the uses in the first set of points above. However, she may have occasionally also encountered curly braces around things that are not a block of statements, e.g. {a:1, b:2}
and have been confused because the contents of those curly braces aren't statements that can be executed. Or, worse, she may not even be able to point to an example she doesn't understand. Instead she just has this gnawing feeling in the back of her mind that code she has encountered written by other people contains curly braces used in unfamiliar ways (though she can't remember where). This makes her suspect that her current understanding of when to use curly braces might be incomplete. Rather than try to find individual examples she doesn't understand, she just wants someone to give her the above list of "rules" of where to use curly braces.
So, again, my question is the following: Can someone describe for me some general principles and/or specific rules that exhaustively describe the use of angle brackets in TypeScript the way I have described the use of curly braces in JavaScript above?
With questions like this, I'd recommend reading the spec, especially the Grammar section. Syntax like < something >
is used in
Type Parameters
< TypeParameterList >
in section 3.6.1Used with declarations and call signatures of classes, interfaces, functions and more
function heat<T>(food: T): T { return food; }
//^^^^^ Type parameter list
class Pizza<T, E extends Cheese> { toppingA: T; toppingB: E }
//^^^^^^^^^^^^^^^^^^^^ Type parameter list
Type Arguments
< TypeArgumentList >
in section 3.6.2Used with references to generic types and calls to generic functions
var pizza: Pizza<Pepperoni, Mozzarella>;
//^^^^^^^^^^^^^^^^^^^^^^ Type argument list
pizza = heat<{ toppingA: Pepperoni, toppingB: Mozzarella}>(ingredients)
//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Type argument list
Update 2018-07-01: As of version 2.9, generic type arguments can also be used in JSX elements and tagged templates.
<MenuItem<Pizza> toppings={[Pepperoni, Mozzarella]} />
//^^^^^^^ Type argument list
const ratingHtml = escapeUserInput<string | number> `Customer ${feedback.customer.username} rated this pizza with <b>${feedback.rating}</b>/10!`
//^^^^^^^^^^^^^^^^ Type argument list
Type Assertions
Defined and used as < Type > UnaryExpression
where UnaryExpression comes from EcmaScript standard in section 4.16
var ingredients = {
toppingA: new Pepperoni,
toppingB: <Mozzarella> fridge.takeSomeCheese()
//^^^^^^^^^^^^ Type assertion
};
JSX expressions (when enabled)
Not documented in the spec, but should follow the the syntax of JSX, which is basically an expression like
<JSXElementName JSXAttributes(optional)> JSXChildren(optional) </JSXElementName>
or
<JSXElementName JSXAttributes(optional) />