?u/p1-90`The document at https://qnighy.github.io/ts-syntax-spec/ is the most accurate and up-to-date version of this specification. It contains the content of the most recently published snapshot plus any modifications that will be included in the next snapshot.
This specification is developed on GitHub. There are a number of ways to contribute to the development of this specification:
Refer to the
Copyright © 2026 Ecma International (for the parts of this specification derived from ECMA-262).
Copyright © 2026 Masaki Hara and contributors.
This specification is licensed under the MIT License.
This document provides an unofficial specification for the syntax and
TypeScript extends ECMAScript with type annotations, type declarations, and a small number of additional expression and statement forms. This specification aims to precisely define the syntax of these extensions and, where applicable, their
This is not an official specification endorsed by Microsoft or any standards body. It is a community effort to document TypeScript's syntax in a format compatible with ECMA-262's conventions.
This specification defines the syntax and
The features described in this specifications are classified into the following categories:
An implementation supporting both TypeScript and JSX doesn't automatically support TSX.
An implementation must first conform to ECMA-262 as described in the original spec's
To conform to this specification, an implementation must support some or all of the categories as well as ECMA-262's conformance requirements, and clearly document which categories are supported.
This "conformance" is what the conformance requirements would be if this specification were an authoritative standard.
In reality, there is no authority for this specification to enforce conformance.
If an implementation supports TypeScript syntax, it must be able to parse a source using a
If an implementation supports JSX syntax, it must be able to parse a source using a
JSX semantics is highly dependent on user configuration, such as Babel config. Hence, we assume that additional custom static analysis is performed to fully fulfill UI frameworks' needs.
As such, this specification only describes a base semantics that a custom transpiler plugin works on.
A conforming implementation supporting JSX must document the values of
For example, in React Automatic JSX Runtime, if an attribute named key precedes any spread attributes in the element, the key attribute is evaluated after all the other attributes.
This is a React-specific transformation not documented normatively in this specification.
If an implementation supports TSX syntax, it must be able to parse a source using a
TSX does not have its own subfeatures; an implementation supporting TSX must consistently support subfeatures for TypeScript and JSX in TSX mode as well.
The following documents are referred to in the text in such a way that some or all of their content constitutes requirements of this document. For dated references, only the edition cited applies. For undated references, the latest edition of the referenced document (including any amendments) applies.
ECMA-262, ECMAScript® Language Specification.
https://tc39.es/ecma262/
TypeScript Documentation.
https://www.typescriptlang.org/docs/
This specification follows the same notational conventions as defined by ECMA-262 (Notational conventions).
This specification follows the same grammar notation convention as defined by ECMA-262 (Grammar Notation), including grammatical parameters and lookahead restrictions. Grammar productions in this specification extend those defined in ECMA-262.
ECMAScript and TypeScript, despite their compatibility, have totally different principles for their grammar:
To accommodate this difference, this specification is written intentionally in a different style to describe grammar constructs that require explicit disambiguation.
Behavior of TypeScript programs depends on how the implementation is configured. To formalize its interface, this specification introduces the concept of syntax context attached to a source text being parsed.
When a TypeScript source text is being matched against a
The current syntax context is defined as follows:
Some nonterminals define syntax alterations. They are like conditionals [+Await] / [~Await] but is matched against the
When a
For simplicity, this specification reuses ECMAScript's
A production in this specification may be mapped to a production in ECMA-262. In such cases, the
This specification may override some of the derived
For example, if the following production:
is
Then the transformation is uniquely determined because the only way to reconstruct the original production is by removing the two optional annotations.
This section extends
This section extends
The source text matched by a grammar production or
For example, ((): number => 0).toString() typically yields "() => 0".
This section extends
This section extends
The Syntax Context Record type is used to represent the configuration of the parser that affects syntaxes added in this specification.
| Field Name | Value | Meaning |
|---|---|---|
| [[TypeScript]] | a Boolean | Indicates whether the parser is currently parsing TypeScript syntax. |
| [[JSX]] | a Boolean | Indicates whether the parser is currently parsing JSX syntax. |
| [[JSXLazy]] | a Boolean | Indicates whether evaluation of expressions in JSX elements should be deferred until necessary. |
A
[[JSXLazy]] is intended to represent the "DOM Expressions" semantics, which is primarily used by Solid.
The default Syntax Context Record is the
The abstract operation IsValidJSXElement takes arguments ctx (a
This is a UI framework-specific hook to rule out specific JSX constructs.
For example, React rejects
The abstract operation EvaluateJSXElement takes arguments ctx (a
In React, the list of children of jsx value goes through additional modifications before being passed to React.createElement, jsx, or jsxs.
The JSX Skeleton Record types are used to represent the structure of JSX elements in a way that can be statically processed by
A JSX Child Skeleton Value is a value that can appear as a child of a JSX element or fragment. It is one of the following:
A JSX Attribute Skeleton Value is
The JSX Element Skeleton Record type is a
| Field Name | Value | Meaning |
|---|---|---|
| [[ElementName]] | a String or |
Represents the name of the JSX element. |
| [[Attributes]] | a list of |
Represents the attributes of the JSX element. |
| [[Children]] | a list of |
Represents the children of the JSX element. |
The JSX Fragment Skeleton Record type is a
| Field Name | Value | Meaning |
|---|---|---|
| [[Children]] | a list of |
Represents the children of the JSX fragment. |
The JSX Attribute Skeleton Record type is a
| Field Name | Value | Meaning |
|---|---|---|
| [[AttributeName]] | a String | Represents the name of the JSX attribute. |
| [[AttributeValue]] | a String, |
Represents the value of the JSX attribute. It is |
The JSX Record types are used to represent the structure of JSX elements in a way that can be dynamically processed by
A JSX Child Value is a value that can appear as a child of a JSX element or fragment. It is one of the following:
A JSX Attribute Value is a
The JSX Element Record type is a
| Field Name | Value | Meaning |
|---|---|---|
| [[ElementName]] | a String or a |
Represents the name of the JSX element. |
| [[Attributes]] | a list of |
Represents the attributes of the JSX element. |
| [[Children]] | a list of |
Represents the children of the JSX element. |
The JSX Element Name Expression Record type is a
| Field Name | Value | Meaning |
|---|---|---|
| [[Value]] | an |
Represents the result of evaluating the expression of the element name. |
The JSX Fragment Record type is a
| Field Name | Value | Meaning |
|---|---|---|
| [[Children]] | a list of |
Represents the children of the JSX fragment. |
The JSX Attribute Record type is a
| Field Name | Value | Meaning |
|---|---|---|
| [[AttributeName]] | a String | Represents the name of the JSX attribute. |
| [[AttributeValue]] | a String, |
Represents the value of the JSX attribute. It is |
The JSX Attribute Expression Record type is a
| Field Name | Value | Meaning |
|---|---|---|
| [[Value]] | an |
Represents the result of evaluating the expression of the attribute value. |
| [[Lazy]] | a Boolean | If true, [[Value]] is a |
The JSX Spread Attribute Record type is a
| Field Name | Value | Meaning |
|---|---|---|
| [[Value]] | an |
Represents the result of evaluating the expression of the spread attribute. |
| [[Lazy]] | a Boolean | If true, [[Value]] is a |
The JSX Child Expression Record type is a
| Field Name | Value | Meaning |
|---|---|---|
| [[Value]] | an |
Represents the result of evaluating the expression of the child. |
| [[Lazy]] | a Boolean | If true, [[Value]] is a |
The JSX Children Spread Expression Record type is a
| Field Name | Value | Meaning |
|---|---|---|
| [[Value]] | an |
Represents the result of evaluating the expression of the spread child. |
| [[Lazy]] | a Boolean | If true, [[Value]] is a |
For the purposes of this document, the following terms and definitions apply.
the process of removing type annotations and type-only declarations from TypeScript source code, producing valid ECMAScript source code.
a syntactic construct that specifies the type of a variable, parameter, return value, or other declaration, and which is removed during
The TypeScript Compiler, the official TypeScript implementation developed by Microsoft.
The term "TypeScript" is a trademark of Microsoft Corporation and is primarily used in the following two senses:
This community specification aims to clarify the syntax and
This specification aims to overcome these difficulties and propose a provisional specification suitable as a starting point for discussions within the TypeScript community. It defines the language specification based on the following criteria:
It should be noted that the TypeScript language defined in this specification is unofficial and arbitrary, and possesses no binding force or authority.
This section extends
In addition to those defined in this section, specialized
This specification extends
See each grammar production for details.
This section extends
This section extends
This section extends
This section extends
This section extends
await, yield, and super expressions.
We have modified
Although arbitrary expressions typically do not appear in these syntaxes, they may be called recursively as
The
The caller must not rely on object identity or modify the returned
It is defined piecewise over the following productions:
The
The abstract operation CreateThunk takes argument expr (an
( and ) if expr starts with {.=>, and body.This section extends
x! = e, (<T>x) = e, (x as T) = e, (x satisfies T) = e are valid according to these rules.
Actual parsers implement these rules in various ways.
x<T> = e.TypeScript's lexical grammar is largely identical to
< and >The following productions use < and > as angle brackets:
Additionally, the following grammar is used for lookahead to detect type arguments:
When < or > in such productions is expected, the parser needs to rescan the following tokens to correctly interpret them as angle brackets:
<<>>>>>>>=>=<= and <<= do not involve rescanning, as they cannot be reinterpreted as part of valid TypeScript syntax.
The following examples illustrate the need for rescanning:
type T = Readonly<Partial<U>>;, the token >> is split into two tokens.type T = Readonly<Partial<Omit<U, keyof V>>>;, the token >>> is split into three tokens.type T<U>= V;, the token >= is split into two tokens.type T<K extends Exclude<keyof U, keyof V>>= W;, the token >>= is split into three tokens.f<<T>() => void>();, the token << is split into two tokens.It is possible to implement the rescanning inversely, first tokenizing them as one-letter tokens and then combining them as needed. >.
Where
The possible occurrences of this goal are:
<< /<, because it is still ambiguous with :.>}, >, or Typically you can tokenize
- character.
Trailing -s and consecutive -s are also allowed.
The latter implies the former. We structure the Early Errors here as such to reflect nuances in parser implementations.
The latter rule follows absence of
Actual parsers implement these rules in various ways.
-).The
It extends IdentifierCodePoints.
The
It extends IdentifierCodePoint.
The
-, return The
Examples:
<div /> is "div", a string literal, because it starts with an ASCII lowercase letter.<my-component /> is "my-component", a string literal, because it contains a -. It also starts with an ASCII lowercase letter.<My-Component /> is "My-Component", a string literal, because it contains a -.<MyComponent /> is MyComponent, an identifier, because it does not start with an ASCII lowercase letter and does not contain a -.<あ /> is あ, an identifier, because あ is not a lowercase letter.<π /> is π, an identifier. Although π is a lowercase letter, it is not a part of ASCII.<à /> depends on whether à is represented in its NFC or NFD form. In its NFC form, it is an identifier as the first code point à is not in ASCII. In its NFD form, it is a string literal as the first code point is a.Where
The possible occurrences of this goal are:
>>} or / >Note the lexical goal after
The parser must not apply usual whitespace/comment skipping rules in this context. The tokenization rule is totally different here from other contexts.
</ here in addition. See note in
For this goal,
Unlike ordinary tokenization goals, this goal does not have
The following nonterminals are defined for use in this goal:
JSX Text is the longest sequence terminated by a { or <, and interpreted as follows:
& that does not start a valid character reference is interpreted as a literal &.JavaScript comments or JavaScript string escapes are not interpreted within JSX text.
Actual parsers implement these rules in various ways.
> and } in &.Where
As usual,
Typically you can tokenize
The only occurrence of this goal is after = in
JSX String Literals do not interpret backslash escapes or line continuations. They instead interpret character references.
JSX String Literals allow multi-line strings and they are interpreted as it is represented in the source code. It contradicts ECMAScript's implicit contract that the three kinds of newlines in source code can be safely normalized.
&.&.There is a difference in how character references are handled in JSX compared to HTML parsing:
Unlike HTML, omission of ; in a character reference results in a verbatim interpretation of the & character.
Unlike HTML, numbered character references to C1 control characters are interpreted as they are; they are not replaced with the corresponding Windows-1252 characters.
Actual parsers implement these rules in various ways.
Type semantics is out of scope for this specification.
< operators:
f < x.#y > (z), where #y is defined in the enclosing classawait and yield eval and argumentsActual parsers implement these rules in various ways.
These rules are here to disallow escaped
Type identifiers following . is
< operators:
f < x.#y > (z), where #y is defined in the enclosing classwith
Before TypeScript 6.0, assert was allowed as an alternative to the with
< operators:
f < import(x) > (x)f < import.meta > (x)Parsers may need one-token lookahead to disambiguate
It implies that legacy octal/non-octal literals and legacy octal/non-octal escapes are not allowed in strict mode.
Actual parsers implement these rules in various ways.
Actual parsers implement these rules in various ways.
this TypeActual parsers implement these rules in various ways.
The index type in
A valid index key type is
string type,number type,symbol type,Unlike in most other occurrences, readonly in mapped types allows newlines after it.
Parsers may need three-token lookahead to disambiguate
Actual parsers implement these rules in various ways.
Actual parsers implement these rules in various ways.
unique and asserts are not listed here.
Newlines before extends are allowed in
There is ambiguity in how to interpret extends. Recursive conditional types are banned in the enclosing conditional type's constraint to help resolve this ambiguity.
Examples:
0 extends infer T extends 0 ? 0 : 0 is equivalent to 0 extends (infer T extends 0) ? 0 : 00 extends infer T extends 0 ? 0 : 0 ? 0 : 0 looks like 0 extends (infer T extends 0 ? 0 : 0) ? 0 : 0, but it's actually syntax error to resolve ambiguity.0 extends (infer T extends 0) ? 0 : 0 reads as it is.0 extends (infer T extends 0 ? 0 : 0) ? 0 : 0 is equivalent to 0 extends ((infer T) extends 0 ? 0 : 0) ? 0 : 0.However, there is one caveat: some parsers including
For example, 0 extends () => infer T extends 0 ? 0 : 0 ? 0 : 0 is allowed. In this case, it prefers interpretation as conditional types if ? follows the constraint type.
The resulting disambiguation algorithm is as follows:
Newlines are allowed between abstract and new.
Parsers may need unbounded lookahead to disambiguate ().
Actual parsers implement these rules in various ways.
The lookahead rule means that function f(): keyof is {} is understood as a function signature that asserts the type of the variable keyof, rather than a function that returns a key of type is.
Parsers may need one-token lookahead to disambiguate asserts from this from
Actual parsers implement these rules in various ways.
asserts and this is as types of higher precedence, and then reports non-grammatical errors later.is type predicates in accessors and asserts x / asserts this and is.Actual parsers implement these rules in various ways.
unique symbol as types of higher precedence, and then reports non-grammatical errors later.Type parameter list cannot be empty.
Not all occurrences of
The restriction only apply to generic arrow functions, and additionally to generic async arrow functions in some parser.
By default,
However, when [[TypeScript]] of the
You can use trailing comma to disambiguate generic arrow functions of one type parameter from JSX elements, such as <T,>(x: T) => x.
Using yield and await.
Actual parsers implement these rules in various ways.
See notes in
And when [[TypeScript]] of the
Type argument list cannot be empty.
<, >, +, -, and /= do not follow type arguments.(, By default,
However, when [[TypeScript]] of the
Actual parsers implement these rules in various ways.
This section extends
The following grammar extends PrimaryExpression:
Disambiguation between
Actual parsers implement these rules in various ways.
<div />.$$type is disallowed in those parsers.The following grammar extends MemberExpression:
The following grammar extends CallExpression:
The following grammar extends OptionalChain:
Disambiguation between
new expression are called Instantiation Expressions.
Before TypeScript 4.7, there is no Instantiation Expressions, and the grammer was instead:
Most TypeScript parsers represent these constructions differently from Instantiation Expressions.
The
The following grammar extends UnaryExpression:
When [[TypeScript]] of the
Only one of JSX tags and legacy type assertions can be enabled at a time. When neither of [[TypeScript]] nor [[JSX]] is enabled, the choice is arbitrary as we would rule it out with Early Errors anyway. We choose to enable JSX tags in this case to imitate
The following grammar extends RelationalExpression:
The production for < is modified from the original ECMA-262 grammar to include a lookahead restriction that prevents ambiguity with
Its semantics is the same, as the derivation tree is unchanged.
This modification takes effect only when [[TypeScript]] is
This section extends
The following grammar extends Declaration:
The following grammar extends LexicalBinding:
The following grammar extends VariableDeclaration:
The [+In] condition is used here to forbid the use of the definite assignment assertion (!) in for statements.
Actual parsers implement these rules in various ways.
!) to be used together with initializers.!) to be used without type annotations.!) to be used in for statements as well.The following productions:
are
The following production:
is
Transformation is uniquely determined because
The following productions:
are
The following production:
is
Transformation is uniquely determined because
The Early Error rules for ! without
for StatementThis specification does not update for statements are updated through
for-in, for-of, and for-await-of StatementsThis specification does not currently update
Actual parsers implement these rules in various ways.
! in the variable declarations of for-in, for-of, and for-await-of statements.for-in, for-of, and for-await-of statements as well.try StatementThe following grammar extends CatchParameter:
The index type in unknown or any, but it's beyond parsers' capabilities to enforce this.
It also means that it is meaningless to have
The following productions:
are
Initializers are only allowed here only when it is a declare const initialized with literal-like values without type annotations.
null cannot be used as an initializer in declare const.
Interestingly, initializers can be currently used in conjunction with binding patterns, enabling use of declare const { length } = "foo";.
Actual parsers implement these rules in various ways.
declare const initializers.declare let and declare var as well.There is no async and/or generator ambient function declarations. async and * are stripped when generating declaration files.
This restriction is fairly marginal; it can be thought of as syntax error or type error. Here we classify it as a type error.
Actual parsers implement these rules in various ways.
This section extends
The following grammar extends FormalParameters:
The following grammar extends FunctionRestParameter:
The following grammar extends FormalParameter:
The following production:
is
The following productions:
are
function f(this) {} is allowed in TypeScript, but not in JavaScript, despite this without
The this parameter. It is defined piecewise over the following productions:
The following grammar extends FunctionDeclaration:
The following grammar extends FunctionExpression:
The following productions:
are
The following production:
is
The following grammar extends ArrowParameters:
Disambiguation between
The following grammar extends MethodDefinition:
Actual parsers implement these rules in various ways.
get and set accessors.set accessors.get accessors.this parameters in get and set accessors.This note also applies to
The following production:
is
The following production:
is
Actual parsers implement these rules in various ways.
this parameters in The following grammar extends GeneratorDeclaration:
The following grammar extends GeneratorExpression:
The following grammar extends GeneratorMethod:
Generators cannot have meaningful type predicates because their return types cannot be void or boolean. We allow them here nonetheless because the errors are more like type errors than syntax errors.
The following productions:
are
The following production:
is
The following production:
is
Async generators cannot have meaningful type predicates because their return types cannot be void or boolean. We allow them here nonetheless because the errors are more like type errors than syntax errors.
The following productions:
are
The following production:
is
The following production:
is
Async functions cannot have meaningful type predicates because their return types cannot be void or boolean. We allow them here nonetheless because the errors are more like type errors than syntax errors.
The following productions:
are
The following production:
is
The following production:
is
The following grammar extends AsyncArrowFunction:
The following grammar extends AsyncArrowHead:
Disambiguation between
This specification slightly alters the use of
This is to accommodate the removal of cover grammars; the use of an identifier named yield in an async arrow function parameter list in a non-strict generator context should have been ruled out when first parsed as
This means yield is recognized as a yield expression instead, but the expression would instead be forbidden by the Early Error rule for
Async arrow functions cannot have meaningful type predicates because their return types cannot be void or boolean. We allow them here nonetheless because the errors are more like type errors than syntax errors.
Actual parsers implement these rules in various ways.
<\u{74}his /> as equivalent to ThisExpression.
For implementations that disallow escaped identifiers in JSX elements, this.
yield or await.
All
Actual parsers implement these rules in various ways.
In fact, these rules are artificial conditions to ensure sanity of the generated code, and many parsers just emit broken code.
Whitespace is allowed within JSX elements where it is disallowed in HTML.
For example, the following are all valid JSX elements:
< div ></ div >< div >< / div >, though < /**/div/**/title/**/=/**/"value"/**/></ /**/div/**/>< img / ><svg : path></svg : path>Actual parsers implement these rules in various ways.
< and /.</ as a single token, thus allowing:
<div><///
div>;
</ as a single token where it is expected, thus disallowing <div></**/img/></div>. However, they still accept </**/img/> as a See
When [[TypeScript]] of the
with:
Based on the rules above, you would better avoid naming an attribute extends or naming an intrinsic element const.
Actual parsers implement these rules in various ways.
The lookahead above is based on the negation of
However, there is a fundamental disagreement among parsers how to disambiguate <: a bounded or unbounded lookahead.
This spec is based on bounded lookahead, which is more conservative.
When [[TypeScript]] of the
leaving no productions for
Therefore, for TypeScript source without JSX, < at the start of an expression is always interpreted as the less-than operator.
<var/> is a valid JSX element.
Actual parsers implement these rules in various ways.
We resolve all expressions to values rather than references here and now, as all known transforms use them as values.
Actual parsers implement these rules in various ways.
{ }.Ordinary JavaScript comments cannot appear as part of
{/* comment */}.
The production can also be used to split two text nodes, like <div>foo{}bar</div>.
Actual parsers implement these rules in various ways.
{ } or { ... }.This section extends
This subclause extends
ECMAScript forbids extension of the Syntactic Grammar in a way that allows the token : is allowed to immediately follow
This relaxation will not invalidate the original specification's intent, as TypeScript code is not intended to be directly executed in the standard Web environment.
There are 253 available named character references total.
Among these, 252 are those listed by HTML 4.01 Specification. The remaining one is ' for ASCII single quote.
Those that were later added in HTML Living Standard, except for ', are not included.
The
| Name | |
|---|---|
AElig |
U+00C6 |
Aacute | U+00C1 |
Acirc | U+00C2 |
Agrave | U+00C0 |
Alpha | U+0391 |
Aring | U+00C5 |
Atilde | U+00C3 |
Auml | U+00C4 |
Beta | U+0392 |
Ccedil | U+00C7 |
Chi | U+03A7 |
Dagger | U+2021 |
Delta | U+0394 |
ETH | U+00D0 |
Eacute | U+00C9 |
Ecirc | U+00CA |
Egrave | U+00C8 |
Epsilon | U+0395 |
Eta | U+0397 |
Euml | U+00CB |
Gamma | U+0393 |
Iacute | U+00CD |
Icirc | U+00CE |
Igrave | U+00CC |
Iota | U+0399 |
Iuml | U+00CF |
Kappa | U+039A |
Lambda | U+039B |
Mu | U+039C |
Ntilde | U+00D1 |
Nu | U+039D |
OElig | U+0152 |
Oacute | U+00D3 |
Ocirc | U+00D4 |
Ograve | U+00D2 |
Omega | U+03A9 |
Omicron | U+039F |
Oslash | U+00D8 |
Otilde | U+00D5 |
Ouml | U+00D6 |
Phi | U+03A6 |
Pi | U+03A0 |
Prime | U+2033 |
Psi | U+03A8 |
Rho | U+03A1 |
Scaron | U+0160 |
Sigma | U+03A3 |
THORN | U+00DE |
Tau | U+03A4 |
Theta | U+0398 |
Uacute | U+00DA |
Ucirc | U+00DB |
Ugrave | U+00D9 |
Upsilon | U+03A5 |
Uuml | U+00DC |
Xi | U+039E |
Yacute | U+00DD |
Yuml | U+0178 |
Zeta | U+0396 |
aacute | U+00E1 |
acirc | U+00E2 |
acute | U+00B4 |
aelig | U+00E6 |
agrave | U+00E0 |
alefsym | U+2135 |
alpha | U+03B1 |
amp | U+0026 |
and | U+2227 |
ang | U+2220 |
apos | U+0027 |
aring | U+00E5 |
asymp | U+2248 |
atilde | U+00E3 |
auml | U+00E4 |
bdquo | U+201E |
beta | U+03B2 |
brvbar | U+00A6 |
bull | U+2022 |
cap | U+2229 |
ccedil | U+00E7 |
cedil | U+00B8 |
cent | U+00A2 |
chi | U+03C7 |
circ | U+02C6 |
clubs | U+2663 |
cong | U+2245 |
copy | U+00A9 |
crarr | U+21B5 |
cup | U+222A |
curren | U+00A4 |
dArr | U+21D3 |
dagger | U+2020 |
darr | U+2193 |
deg | U+00B0 |
delta | U+03B4 |
diams | U+2666 |
divide | U+00F7 |
eacute | U+00E9 |
ecirc | U+00EA |
egrave | U+00E8 |
empty | U+2205 |
emsp | U+2003 |
ensp | U+2002 |
epsilon | U+03B5 |
equiv | U+2261 |
eta | U+03B7 |
eth | U+00F0 |
euml | U+00EB |
euro | U+20AC |
exist | U+2203 |
fnof | U+0192 |
forall | U+2200 |
frac12 | U+00BD |
frac14 | U+00BC |
frac34 | U+00BE |
frasl | U+2044 |
gamma | U+03B3 |
ge | U+2265 |
gt | U+003E |
hArr | U+21D4 |
harr | U+2194 |
hearts | U+2665 |
hellip | U+2026 |
iacute | U+00ED |
icirc | U+00EE |
iexcl | U+00A1 |
igrave | U+00EC |
image | U+2111 |
infin | U+221E |
int | U+222B |
iota | U+03B9 |
iquest | U+00BF |
isin | U+2208 |
iuml | U+00EF |
kappa | U+03BA |
lArr | U+21D0 |
lambda | U+03BB |
lang | U+2329 |
laquo | U+00AB |
larr | U+2190 |
lceil | U+2308 |
ldquo | U+201C |
le | U+2264 |
lfloor | U+230A |
lowast | U+2217 |
loz | U+25CA |
lrm | U+200E |
lsaquo | U+2039 |
lsquo | U+2018 |
lt | U+003C |
macr | U+00AF |
mdash | U+2014 |
micro | U+00B5 |
middot | U+00B7 |
minus | U+2212 |
mu | U+03BC |
nabla | U+2207 |
nbsp | U+00A0 |
ndash | U+2013 |
ne | U+2260 |
ni | U+220B |
not | U+00AC |
notin | U+2209 |
nsub | U+2284 |
ntilde | U+00F1 |
nu | U+03BD |
oacute | U+00F3 |
ocirc | U+00F4 |
oelig | U+0153 |
ograve | U+00F2 |
oline | U+203E |
omega | U+03C9 |
omicron | U+03BF |
oplus | U+2295 |
or | U+2228 |
ordf | U+00AA |
ordm | U+00BA |
oslash | U+00F8 |
otilde | U+00F5 |
otimes | U+2297 |
ouml | U+00F6 |
para | U+00B6 |
part | U+2202 |
permil | U+2030 |
perp | U+22A5 |
phi | U+03C6 |
pi | U+03C0 |
piv | U+03D6 |
plusmn | U+00B1 |
pound | U+00A3 |
prime | U+2032 |
prod | U+220F |
prop | U+221D |
psi | U+03C8 |
quot | U+0022 |
rArr | U+21D2 |
radic | U+221A |
rang | U+232A |
raquo | U+00BB |
rarr | U+2192 |
rceil | U+2309 |
rdquo | U+201D |
real | U+211C |
reg | U+00AE |
rfloor | U+230B |
rho | U+03C1 |
rlm | U+200F |
rsaquo | U+203A |
rsquo | U+2019 |
sbquo | U+201A |
scaron | U+0161 |
sdot | U+22C5 |
sect | U+00A7 |
shy | U+00AD |
sigma | U+03C3 |
sigmaf | U+03C2 |
sim | U+223C |
spades | U+2660 |
sub | U+2282 |
sube | U+2286 |
sum | U+2211 |
sup1 | U+00B9 |
sup2 | U+00B2 |
sup3 | U+00B3 |
sup | U+2283 |
supe | U+2287 |
szlig | U+00DF |
tau | U+03C4 |
there4 | U+2234 |
theta | U+03B8 |
thetasym | U+03D1 |
thinsp | U+2009 |
thorn | U+00FE |
tilde | U+02DC |
times | U+00D7 |
trade | U+2122 |
uArr | U+21D1 |
uacute | U+00FA |
uarr | U+2191 |
ucirc | U+00FB |
ugrave | U+00F9 |
uml | U+00A8 |
upsih | U+03D2 |
upsilon | U+03C5 |
uuml | U+00FC |
weierp | U+2118 |
xi | U+03BE |
yacute | U+00FD |
yen | U+00A5 |
yuml | U+00FF |
zeta | U+03B6 |
zwj | U+200D |
zwnj | U+200C |
It affects the way TypeScript handles
In ? after ? would first be interpreted as part of a permissive optional type.
In the main grammar, unique is restricted to unique symbol in
The infer ... extends constraint uses Type[+Cond] for the constraint.
infer T extends Constraint from conditional types as follows: it greedily parses the constraint (with disallowConditionalTypesAnd), then checks whether ? follows. If conditional types are enabled in the outer context and ? follows, extends belongs to the enclosing conditional type instead. If conditional types are disabled ([~Cond]), the constraint is always kept.
The four infer alternatives each represent a distinct case:
infer T [lookahead != extends] — bare infer when extends does not follow. Available in both [+Cond] and [~Cond].infer T extends Constraint — constrained infer. infer T [lookahead = extends Constraint ?] — bare infer when extends Constraint ? follows. This models ? after it, and discards the constraint. The bare infer T then becomes part of the check type of the enclosing infer T extends Constraint [lookahead != ?] — constrained infer when ? does not follow the constraint. In [~Cond] context, [lookahead != extends] and extends make the two alternatives mutually exclusive.
In [+Cond] context, the complex lookahead on the bare alternative and [lookahead != ?] on the constrained alternative partition the extends-follows cases by whether ? follows the constraint, making all three [+Cond] alternatives mutually exclusive.
In the main grammar, asserts and this is type predicates only appear in asserts x / asserts this and is (see
In the main grammar, x is type predicates only appear in identifier [no LineTerminator here] is).
< as starting a function type, new as starting a abstract new as starting a >) and fallback alternatives to ensure they always match some prefix when their starting tokens are present.
( starts a function type by checking whether the parenthesized content looks like formal parameters (e.g. (), (..., (x:, (x,, (x?, (x=, or (x) =>). The [lookahead != `=>`] restriction on the grouped type ( ) in => follows the closing parenthesis. The grouped type uses ).
This specification is authored on GitHub in a plaintext source format called Ecmarkup. Ecmarkup is an HTML and Markdown dialect that provides a framework and toolset for authoring ECMAScript specifications in plaintext and processing the specification into a full-featured HTML rendering that follows the editorial conventions for this document. Ecmarkup builds on and integrates a number of other formats and technologies including Grammarkdown for defining syntax and Ecmarkdown for authoring algorithm steps. PDF renderings of this specification are produced by printing the HTML rendering to a PDF.