2.2 Names

A core purpose of the TypeScript compiler is to track the named entities in a program and validate that they are used according to their designated meaning. Names in TypeScript can be written in several ways, depending on context. Specifically, a name can be written as

  • an IdentifierName,
  • a StringLiteral in a property name,
  • a NumericLiteral in a property name, or
  • a ComputedPropertyName that denotes a well-known symbol (2.2.3).

Most commonly, names are written to conform with the Identifier production, which is any IdentifierName that isn’t a reserved word.

2.2.1 Reserved Words

The following keywords are reserved and cannot be used as an Identifier:

  1. break case catch class
  2. const continue debugger default
  3. delete do else enum
  4. export extends false finally
  5. for function if import
  6. in instanceof new null
  7. return super switch this
  8. throw true try typeof
  9. var void while with

The following keywords cannot be used as identifiers in strict mode code, but are otherwise not restricted:

  1. implements interface let package
  2. private protected public static
  3. yield

The following keywords cannot be used as user defined type names, but are otherwise not restricted:

  1. any boolean number string
  2. symbol

The following keywords have special meaning in certain contexts, but are valid identifiers:

  1. abstract as async await
  2. constructor declare from get
  3. is module namespace of
  4. require set type

2.2.2 Property Names

The PropertyName production from the ECMAScript grammar is reproduced below:

  PropertyName:   LiteralPropertyName   ComputedPropertyName

  LiteralPropertyName:   IdentifierName   StringLiteral   NumericLiteral

  ComputedPropertyName:   [AssignmentExpression]

A property name can be any identifier (including a reserved word), a string literal, a numeric literal, or a computed property name. String literals may be used to give properties names that are not valid identifiers, such as names containing blanks. Numeric literal property names are equivalent to string literal property names with the string representation of the numeric literal, as defined in the ECMAScript specification.

2.2.3 Computed Property Names

ECMAScript 2015 permits object literals and classes to declare members with computed property names. A computed property name specifies an expression that computes the actual property name at run-time. Because the final property name isn’t known at compile-time, TypeScript can only perform limited checks for entities declared with computed property names. However, a subset of computed property names known as well-known symbols can be used anywhere a PropertyName is expected, including property names within types. A computed property name is a well-known symbol if it is of the form

  1. [ Symbol . xxx ]

In a well-known symbol, the identifier to the right of the dot must denote a property of the primitive type symbol in the type of the global variable ‘Symbol’, or otherwise an error occurs.

In a PropertyName that specifies a ComputedPropertyName, the computed property name is required to denote a well-known symbol unless the property name occurs in a property assignment of an object literal (4.5) or a property member declaration in a non-ambient class (8.4).

Below is an example of an interface that declares a property with a well-known symbol name:

  1. interface Iterable<T> {
  2. [Symbol.iterator](): Iterator<T>;
  3. }

TODO: Update to reflect treatment of computed property names with literal expressions.