Rules for the use of angle brackets in Typescript

Andrew Willems picture Andrew Willems · May 21, 2016 · Viewed 14.3k times · Source

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 exported or imported from a module,

  • cases following a switch criterion, or

  • enums.

(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?

Answer

noppa picture noppa · May 22, 2016

With questions like this, I'd recommend reading the spec, especially the Grammar section. Syntax like < something > is used in

  1. Type Parameters

    • Defined as < TypeParameterList > in section 3.6.1
    • Used 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
      
  2. Type Arguments

    • Defined as < TypeArgumentList > in section 3.6.2
    • Used 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
      
  3. Type Assertions

  4. 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) />