Skip to content

Commit 7cd39e3

Browse files
committed
Parsing of mapped types
1 parent 7b34b61 commit 7cd39e3

5 files changed

Lines changed: 51 additions & 1 deletion

File tree

src/compiler/binder.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3099,6 +3099,7 @@ namespace ts {
30993099
case SyntaxKind.ThisType:
31003100
case SyntaxKind.TypeOperator:
31013101
case SyntaxKind.IndexedAccessType:
3102+
case SyntaxKind.MappedType:
31023103
case SyntaxKind.LiteralType:
31033104
// Types and signatures are TypeScript syntax, and exclude all other facts.
31043105
transformFlags = TransformFlags.AssertTypeScript;

src/compiler/checker.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6002,6 +6002,8 @@ namespace ts {
60026002
return getTypeFromTypeOperatorNode(<TypeOperatorNode>node);
60036003
case SyntaxKind.IndexedAccessType:
60046004
return getTypeFromIndexedAccessTypeNode(<IndexedAccessTypeNode>node);
6005+
case SyntaxKind.MappedType:
6006+
return unknownType; // !!!
60056007
// This function assumes that an identifier or qualified name is a type expression
60066008
// Callers should first ensure this by calling isTypeNode
60076009
case SyntaxKind.Identifier:
@@ -15072,6 +15074,10 @@ namespace ts {
1507215074
getTypeFromIndexedAccessTypeNode(node);
1507315075
}
1507415076

15077+
function checkMappedType(node: MappedTypeNode) {
15078+
node; // !!!
15079+
}
15080+
1507515081
function isPrivateWithinAmbient(node: Node): boolean {
1507615082
return (getModifierFlags(node) & ModifierFlags.Private) && isInAmbientContext(node);
1507715083
}
@@ -18312,6 +18318,8 @@ namespace ts {
1831218318
return checkSourceElement((<ParenthesizedTypeNode | TypeOperatorNode>node).type);
1831318319
case SyntaxKind.IndexedAccessType:
1831418320
return checkIndexedAccessType(<IndexedAccessTypeNode>node);
18321+
case SyntaxKind.IndexedAccessType:
18322+
return checkMappedType(<MappedTypeNode>node);
1831518323
case SyntaxKind.FunctionDeclaration:
1831618324
return checkFunctionDeclaration(<FunctionDeclaration>node);
1831718325
case SyntaxKind.Block:

src/compiler/parser.ts

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,10 @@ namespace ts {
139139
case SyntaxKind.IndexedAccessType:
140140
return visitNode(cbNode, (<IndexedAccessTypeNode>node).objectType) ||
141141
visitNode(cbNode, (<IndexedAccessTypeNode>node).indexType);
142+
case SyntaxKind.MappedType:
143+
return visitNode(cbNode, (<MappedTypeNode>node).iterationTypeName) ||
144+
visitNode(cbNode, (<MappedTypeNode>node).indexType) ||
145+
visitNode(cbNode, (<MappedTypeNode>node).type);
142146
case SyntaxKind.LiteralType:
143147
return visitNode(cbNode, (<LiteralTypeNode>node).literal);
144148
case SyntaxKind.ObjectBindingPattern:
@@ -2399,6 +2403,30 @@ namespace ts {
23992403
return members;
24002404
}
24012405

2406+
function isStartOfMappedType() {
2407+
nextToken();
2408+
if (token() === SyntaxKind.ReadonlyKeyword) {
2409+
nextToken();
2410+
}
2411+
return token() === SyntaxKind.OpenBracketToken && nextTokenIsIdentifier() && nextToken() === SyntaxKind.InKeyword;
2412+
}
2413+
2414+
function parseMappedType() {
2415+
const node = <MappedTypeNode>createNode(SyntaxKind.MappedType);
2416+
parseExpected(SyntaxKind.OpenBraceToken);
2417+
node.readonlyToken = parseOptionalToken(SyntaxKind.ReadonlyKeyword);
2418+
parseExpected(SyntaxKind.OpenBracketToken);
2419+
node.iterationTypeName = parseIdentifier();
2420+
parseExpected(SyntaxKind.InKeyword);
2421+
node.indexType = parseType();
2422+
parseExpected(SyntaxKind.CloseBracketToken);
2423+
node.questionToken = parseOptionalToken(SyntaxKind.QuestionToken);
2424+
node.type = parseTypeAnnotation();
2425+
parseSemicolon();
2426+
parseExpected(SyntaxKind.CloseBraceToken);
2427+
return finishNode(node);
2428+
}
2429+
24022430
function parseTupleType(): TupleTypeNode {
24032431
const node = <TupleTypeNode>createNode(SyntaxKind.TupleType);
24042432
node.elementTypes = parseBracketedList(ParsingContext.TupleElementTypes, parseType, SyntaxKind.OpenBracketToken, SyntaxKind.CloseBracketToken);
@@ -2472,7 +2500,7 @@ namespace ts {
24722500
case SyntaxKind.TypeOfKeyword:
24732501
return parseTypeQuery();
24742502
case SyntaxKind.OpenBraceToken:
2475-
return parseTypeLiteral();
2503+
return lookAhead(isStartOfMappedType) ? parseMappedType() : parseTypeLiteral();
24762504
case SyntaxKind.OpenBracketToken:
24772505
return parseTupleType();
24782506
case SyntaxKind.OpenParenToken:

src/compiler/transformers/ts.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -302,6 +302,7 @@ namespace ts {
302302
case SyntaxKind.ThisType:
303303
case SyntaxKind.TypeOperator:
304304
case SyntaxKind.IndexedAccessType:
305+
case SyntaxKind.MappedType:
305306
case SyntaxKind.LiteralType:
306307
// TypeScript type nodes are elided.
307308

@@ -1787,6 +1788,7 @@ namespace ts {
17871788
case SyntaxKind.TypeQuery:
17881789
case SyntaxKind.TypeOperator:
17891790
case SyntaxKind.IndexedAccessType:
1791+
case SyntaxKind.MappedType:
17901792
case SyntaxKind.TypeLiteral:
17911793
case SyntaxKind.AnyKeyword:
17921794
case SyntaxKind.ThisType:

src/compiler/types.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -219,6 +219,7 @@ namespace ts {
219219
ThisType,
220220
TypeOperator,
221221
IndexedAccessType,
222+
MappedType,
222223
LiteralType,
223224
// Binding patterns
224225
ObjectBindingPattern,
@@ -519,6 +520,7 @@ namespace ts {
519520
export type EqualsGreaterThanToken = Token<SyntaxKind.EqualsGreaterThanToken>;
520521
export type EndOfFileToken = Token<SyntaxKind.EndOfFileToken>;
521522
export type AtToken = Token<SyntaxKind.AtToken>;
523+
export type ReadonlyToken = Token<SyntaxKind.ReadonlyKeyword>;
522524

523525
export type Modifier
524526
= Token<SyntaxKind.AbstractKeyword>
@@ -897,6 +899,15 @@ namespace ts {
897899
indexType: TypeNode;
898900
}
899901

902+
export interface MappedTypeNode extends TypeNode {
903+
kind: SyntaxKind.MappedType;
904+
readonlyToken?: ReadonlyToken;
905+
iterationTypeName: Identifier;
906+
indexType: TypeNode;
907+
questionToken?: QuestionToken;
908+
type?: TypeNode;
909+
}
910+
900911
export interface LiteralTypeNode extends TypeNode {
901912
kind: SyntaxKind.LiteralType;
902913
literal: Expression;

0 commit comments

Comments
 (0)