Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
7cd39e3
Parsing of mapped types
ahejlsberg Nov 3, 2016
d1a8af5
Parse '[P in K]' part of mapped type as a type parameter declaration
ahejlsberg Nov 3, 2016
fc450a2
Introduce MappedType in type checker
ahejlsberg Nov 4, 2016
ecdb74c
Merge branch 'master' into mappedTypes
ahejlsberg Nov 4, 2016
7807ac9
Attach symbols to mapped types
ahejlsberg Nov 4, 2016
1c7b397
Introduce instantiateCached function
ahejlsberg Nov 5, 2016
507ab30
Handle readonly and optional properties + index signatures
ahejlsberg Nov 6, 2016
2564e1c
Handle recursion in mapped type display
ahejlsberg Nov 6, 2016
5de63a7
Validate constraint type in mapped type
ahejlsberg Nov 7, 2016
de93876
Correct symbol display for type parameter of mapped type
ahejlsberg Nov 7, 2016
9f3aa38
Improve sharing by re-instantiating top level type aliases
ahejlsberg Nov 7, 2016
8aef1e6
Type inference for mapped types
ahejlsberg Nov 8, 2016
7ca5923
Merge branch 'master' into mappedTypes
ahejlsberg Nov 8, 2016
a562d6e
Make keyof T assignable to and subtype of string | number
ahejlsberg Nov 8, 2016
cf2953b
Add relations for keyof S / keyof T and [P in S]: X / [P in T]: X
ahejlsberg Nov 8, 2016
aca7e2f
Don't include private/protected properties in keyof T
ahejlsberg Nov 8, 2016
3dd11e4
Properly implement type relationship for '[P in S]: X' and '[P in T]: Y'
ahejlsberg Nov 9, 2016
2170ff6
Defer resolution of mapped types to enable recursive definitions
ahejlsberg Nov 10, 2016
b81c226
Use pull model to obtain type alias information for type nodes
ahejlsberg Nov 10, 2016
de2da2c
Accept new baselines
ahejlsberg Nov 10, 2016
aca1ab3
Check mapped type constraint is assignable to string | number
ahejlsberg Nov 10, 2016
64d2698
Merge branch 'master' into mappedTypes
ahejlsberg Nov 10, 2016
cd185f2
Add declaration emit support
ahejlsberg Nov 10, 2016
1c7ec6b
Add missing node visits in forEachChild
ahejlsberg Nov 11, 2016
364142c
Improve type inference for types with same generic type alias
ahejlsberg Nov 11, 2016
e9b6ddc
Add tests
ahejlsberg Nov 11, 2016
ca3f797
More tests
ahejlsberg Nov 11, 2016
5028a44
Accept new baselines
ahejlsberg Nov 11, 2016
9ac7667
Address CR feedback
ahejlsberg Nov 12, 2016
6ceab7b
Accept new baselines
ahejlsberg Nov 12, 2016
cd05c07
Add comment explaining type alias instantiation strategy
ahejlsberg Nov 13, 2016
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Parse '[P in K]' part of mapped type as a type parameter declaration
  • Loading branch information
ahejlsberg committed Nov 3, 2016
commit d1a8af532092378b07e3d441838070e5b5360466
2 changes: 2 additions & 0 deletions src/compiler/binder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1302,6 +1302,7 @@ namespace ts {
case SyntaxKind.JSDocFunctionType:
case SyntaxKind.ModuleDeclaration:
case SyntaxKind.TypeAliasDeclaration:
case SyntaxKind.MappedType:

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

MappedType seems to behave like a TypeLiteral elsewhere, but I'm not why it has HasLocals here like TypeAliasDeclaration does. Is it that MappedType introduces a new name for the parameter type?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is because of the type parameter introduced by [P in ...]. We want that symbol entered into the locals symbol table such that it is accessible within the mapped type, but not from the outside (unlike members).

return ContainerFlags.IsContainer | ContainerFlags.HasLocals;

case SyntaxKind.SourceFile:
Expand Down Expand Up @@ -1421,6 +1422,7 @@ namespace ts {
case SyntaxKind.ArrowFunction:
case SyntaxKind.JSDocFunctionType:
case SyntaxKind.TypeAliasDeclaration:
case SyntaxKind.MappedType:
// All the children of these container types are never visible through another
// symbol (i.e. through another symbol's 'exports' or 'members'). Instead,
// they're only accessed 'lexically' (i.e. from code that exists underneath
Expand Down
18 changes: 15 additions & 3 deletions src/compiler/checker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5834,6 +5834,18 @@ namespace ts {
return links.resolvedType;
}

function getTypeFromMappedTypeNode(node: MappedTypeNode) {
const links = getNodeLinks(node);
if (!links.resolvedType) {
getTypeFromTypeNode(node.typeParameter.constraint);
if (node.type) {
getTypeFromTypeNode(node.type);
}
links.resolvedType = unknownType;
}
return links.resolvedType;
}

function getTypeFromTypeLiteralOrFunctionOrConstructorTypeNode(node: Node, aliasSymbol?: Symbol, aliasTypeArguments?: Type[]): Type {
const links = getNodeLinks(node);
if (!links.resolvedType) {
Expand Down Expand Up @@ -6003,7 +6015,7 @@ namespace ts {
case SyntaxKind.IndexedAccessType:
return getTypeFromIndexedAccessTypeNode(<IndexedAccessTypeNode>node);
case SyntaxKind.MappedType:
return unknownType; // !!!
return getTypeFromMappedTypeNode(<MappedTypeNode>node);
// This function assumes that an identifier or qualified name is a type expression
// Callers should first ensure this by calling isTypeNode
case SyntaxKind.Identifier:
Expand Down Expand Up @@ -15075,7 +15087,7 @@ namespace ts {
}

function checkMappedType(node: MappedTypeNode) {
node; // !!!
getTypeFromMappedTypeNode(node);
}

function isPrivateWithinAmbient(node: Node): boolean {
Expand Down Expand Up @@ -18318,7 +18330,7 @@ namespace ts {
return checkSourceElement((<ParenthesizedTypeNode | TypeOperatorNode>node).type);
case SyntaxKind.IndexedAccessType:
return checkIndexedAccessType(<IndexedAccessTypeNode>node);
case SyntaxKind.IndexedAccessType:
case SyntaxKind.MappedType:
return checkMappedType(<MappedTypeNode>node);
case SyntaxKind.FunctionDeclaration:
return checkFunctionDeclaration(<FunctionDeclaration>node);
Expand Down
15 changes: 10 additions & 5 deletions src/compiler/parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -140,8 +140,7 @@ namespace ts {
return visitNode(cbNode, (<IndexedAccessTypeNode>node).objectType) ||
visitNode(cbNode, (<IndexedAccessTypeNode>node).indexType);
case SyntaxKind.MappedType:
return visitNode(cbNode, (<MappedTypeNode>node).iterationTypeName) ||
visitNode(cbNode, (<MappedTypeNode>node).indexType) ||
return visitNode(cbNode, (<MappedTypeNode>node).typeParameter) ||
visitNode(cbNode, (<MappedTypeNode>node).type);
case SyntaxKind.LiteralType:
return visitNode(cbNode, (<LiteralTypeNode>node).literal);
Expand Down Expand Up @@ -2411,14 +2410,20 @@ namespace ts {
return token() === SyntaxKind.OpenBracketToken && nextTokenIsIdentifier() && nextToken() === SyntaxKind.InKeyword;
}

function parseMappedTypeParameter() {
const node = <TypeParameterDeclaration>createNode(SyntaxKind.TypeParameter);
node.name = parseIdentifier();
parseExpected(SyntaxKind.InKeyword);
node.constraint = parseType();
return finishNode(node);
}

function parseMappedType() {
const node = <MappedTypeNode>createNode(SyntaxKind.MappedType);
parseExpected(SyntaxKind.OpenBraceToken);
node.readonlyToken = parseOptionalToken(SyntaxKind.ReadonlyKeyword);
parseExpected(SyntaxKind.OpenBracketToken);
node.iterationTypeName = parseIdentifier();
parseExpected(SyntaxKind.InKeyword);
node.indexType = parseType();
node.typeParameter = parseMappedTypeParameter();
parseExpected(SyntaxKind.CloseBracketToken);
node.questionToken = parseOptionalToken(SyntaxKind.QuestionToken);
node.type = parseTypeAnnotation();
Expand Down
3 changes: 1 addition & 2 deletions src/compiler/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -902,8 +902,7 @@ namespace ts {
export interface MappedTypeNode extends TypeNode {
kind: SyntaxKind.MappedType;
readonlyToken?: ReadonlyToken;
iterationTypeName: Identifier;
indexType: TypeNode;
typeParameter: TypeParameterDeclaration;
questionToken?: QuestionToken;
type?: TypeNode;
}
Expand Down