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:
break case catch class
const continue debugger default
delete do else enum
export extends false finally
for function if import
in instanceof new null
return super switch this
throw true try typeof
var void while with
The following keywords cannot be used as identifiers in strict mode code, but are otherwise not restricted:
implements interface let package
private protected public static
yield
The following keywords cannot be used as user defined type names, but are otherwise not restricted:
any boolean number string
symbol
The following keywords have special meaning in certain contexts, but are valid identifiers:
abstract as async await
constructor declare from get
is module namespace of
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
[ 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:
interface Iterable<T> {
[Symbol.iterator](): Iterator<T>;
}
TODO: Update to reflect treatment of computed property names with literal expressions.