@@ -1575,6 +1575,10 @@ namespace ts {
1575
1575
}
1576
1576
1577
1577
function symbolIsValue(symbol: Symbol): boolean {
1578
+ if (symbol.partialSource) {
1579
+ return symbolIsValue(symbol.partialSource);
1580
+ }
1581
+
1578
1582
// If it is an instantiated symbol, then it is a value if the symbol it is an
1579
1583
// instantiation of is a value.
1580
1584
if (symbol.flags & SymbolFlags.Instantiated) {
@@ -1630,6 +1634,12 @@ namespace ts {
1630
1634
return type;
1631
1635
}
1632
1636
1637
+ function createPartialTypeFromObjectType(target: Type): Type {
1638
+ const type = <PartialType>createType(TypeFlags.Partial | TypeFlags.ObjectType);
1639
+ type.type = target;
1640
+ return type;
1641
+ }
1642
+
1633
1643
// A reserved member name starts with two underscores, but the third character cannot be an underscore
1634
1644
// or the @ symbol. A third underscore indicates an escaped form of an identifer that started
1635
1645
// with at least two underscores. The @ character indicates that the name is denoted by a well known ES
@@ -2217,6 +2227,10 @@ namespace ts {
2217
2227
}
2218
2228
writer.writeKeyword("this");
2219
2229
}
2230
+ else if (type.flags & TypeFlags.Partial) {
2231
+ writer.writeKeyword("partial ");
2232
+ writeType((type as PartialType).type, flags);
2233
+ }
2220
2234
else if (getObjectFlags(type) & ObjectFlags.Reference) {
2221
2235
writeTypeReference(<TypeReference>type, nextFlags);
2222
2236
}
@@ -2799,6 +2813,7 @@ namespace ts {
2799
2813
case SyntaxKind.UnionType:
2800
2814
case SyntaxKind.IntersectionType:
2801
2815
case SyntaxKind.ParenthesizedType:
2816
+ case SyntaxKind.PartialType:
2802
2817
return isDeclarationVisible(<Declaration>node.parent);
2803
2818
2804
2819
// Default binding, import specifier and namespace import is visible
@@ -3542,7 +3557,24 @@ namespace ts {
3542
3557
return links.type;
3543
3558
}
3544
3559
3560
+ function getTypeOfPartialPropertySymbol(symbol: Symbol): Type {
3561
+ const links = getSymbolLinks(symbol);
3562
+ if (!links.type) {
3563
+ const type = getTypeOfSymbol(symbol.partialSource);
3564
+ if (strictNullChecks) {
3565
+ links.type = getUnionType([type, undefinedType]);
3566
+ }
3567
+ else {
3568
+ links.type = type;
3569
+ }
3570
+ }
3571
+ return links.type;
3572
+ }
3573
+
3545
3574
function getTypeOfSymbol(symbol: Symbol): Type {
3575
+ if (symbol.partialSource) {
3576
+ return getTypeOfPartialPropertySymbol(symbol);
3577
+ }
3546
3578
if (symbol.flags & SymbolFlags.Instantiated) {
3547
3579
return getTypeOfInstantiatedSymbol(symbol);
3548
3580
}
@@ -4199,6 +4231,29 @@ namespace ts {
4199
4231
resolveObjectTypeMembers(type, source, typeParameters, typeArguments);
4200
4232
}
4201
4233
4234
+ function resolvePartialTypeMembers(type: PartialType) {
4235
+ const source = getPropertiesOfType(type.type);
4236
+ const members = createMap<Symbol>();
4237
+ for (const member of source) {
4238
+ if (member.flags & SymbolFlags.Optional) {
4239
+ members[member.name] = member;
4240
+ }
4241
+ else {
4242
+ const synthetic = createSymbol(member.flags | SymbolFlags.SyntheticProperty | SymbolFlags.Optional, member.name);
4243
+ getSymbolLinks(synthetic).originalType = type.type;
4244
+ synthetic.partialSource = member;
4245
+ members[member.name] = synthetic;
4246
+ }
4247
+ }
4248
+ const stringIndex = getIndexInfoOfType(type.type, IndexKind.String);
4249
+ const numberIndex = getIndexInfoOfType(type.type, IndexKind.Number);
4250
+ const stringIndexType = stringIndex && (strictNullChecks ? getUnionType([stringIndex.type, undefinedType]) : stringIndex.type);
4251
+ const numberIndexType = numberIndex && (strictNullChecks ? getUnionType([numberIndex.type, undefinedType]) : numberIndex.type);
4252
+ setObjectTypeMembers(type, members, emptyArray, emptyArray,
4253
+ stringIndex && createIndexInfo(stringIndexType, stringIndex.isReadonly, stringIndex.declaration),
4254
+ numberIndex && createIndexInfo(numberIndexType, numberIndex.isReadonly, numberIndex.declaration));
4255
+ }
4256
+
4202
4257
function createSignature(declaration: SignatureDeclaration, typeParameters: TypeParameter[], thisParameter: Symbol | undefined, parameters: Symbol[],
4203
4258
resolvedReturnType: Type, typePredicate: TypePredicate, minArgumentCount: number, hasRestParameter: boolean, hasLiteralTypes: boolean): Signature {
4204
4259
const sig = new Signature(checker);
@@ -4420,6 +4475,8 @@ namespace ts {
4420
4475
else if ((<ObjectType>type).objectFlags & ObjectFlags.Anonymous) {
4421
4476
resolveAnonymousTypeMembers(<AnonymousType>type);
4422
4477
}
4478
+ else if ((<ObjectType>type).flags & TypeFlags.Partial) {
4479
+ resolvePartialTypeMembers(<PartialType>type);
4423
4480
}
4424
4481
else if (type.flags & TypeFlags.Union) {
4425
4482
resolveUnionTypeMembers(<UnionType>type);
@@ -5695,6 +5752,7 @@ namespace ts {
5695
5752
return links.resolvedType;
5696
5753
}
5697
5754
5755
+ <<<<<<< 7b34b612beda66b0812462a3feeabc63852cd842
5698
5756
function getIndexTypeForTypeParameter(type: TypeParameter) {
5699
5757
if (!type.resolvedIndexType) {
5700
5758
type.resolvedIndexType = <IndexType>createType(TypeFlags.Index);
@@ -5721,7 +5779,17 @@ namespace ts {
5721
5779
function getTypeFromTypeOperatorNode(node: TypeOperatorNode) {
5722
5780
const links = getNodeLinks(node);
5723
5781
if (!links.resolvedType) {
5724
- links.resolvedType = getIndexType(getTypeFromTypeNodeNoAlias(node.type));
5782
+ switch (node.operator) {
5783
+ case SyntaxKind.KeyOfKeyword:
5784
+ links.resolvedType = getIndexType(getTypeFromTypeNodeNoAlias(node.type));
5785
+ break;
5786
+ case SyntaxKind.PartialKeyword:
5787
+ links.resolvedType = getPartialType(getTypeOfNode(node.type));
5788
+ break;
5789
+ default:
5790
+ Debug.fail('Unknown operator of type operator type')
5791
+ break;
5792
+ }
5725
5793
}
5726
5794
return links.resolvedType;
5727
5795
}
@@ -5834,6 +5902,32 @@ namespace ts {
5834
5902
return links.resolvedType;
5835
5903
}
5836
5904
5905
+ function getPartialType(type: Type): Type {
5906
+ if (type.resolvedPartialType) {
5907
+ return type.resolvedPartialType;
5908
+ }
5909
+
5910
+ if (type.flags & TypeFlags.Partial) {
5911
+ // partial partial T === partial T
5912
+ return type;
5913
+ }
5914
+ if (type.flags & TypeFlags.Union) {
5915
+ return type.resolvedPartialType = getUnionType((type as UnionType).types.map(getPartialType));
5916
+ }
5917
+ if (type.flags & TypeFlags.Intersection) {
5918
+ return type.resolvedPartialType = getIntersectionType((type as IntersectionType).types.map(getPartialType));
5919
+ }
5920
+ if (type.flags & TypeFlags.ObjectType) {
5921
+ return type.resolvedPartialType = createPartialTypeFromObjectType(type);
5922
+ }
5923
+
5924
+ // Type parameter
5925
+ Debug.assert(!!(type.flags & TypeFlags.TypeParameter));
5926
+ const result = <PartialType>createType(TypeFlags.Partial);
5927
+ result.type = type;
5928
+ return type.resolvedPartialType = result;
5929
+ }
5930
+
5837
5931
function getTypeFromTypeLiteralOrFunctionOrConstructorTypeNode(node: Node, aliasSymbol?: Symbol, aliasTypeArguments?: Type[]): Type {
5838
5932
const links = getNodeLinks(node);
5839
5933
if (!links.resolvedType) {
@@ -5983,6 +6077,8 @@ namespace ts {
5983
6077
return getTypeFromUnionTypeNode(<UnionTypeNode>node, aliasSymbol, aliasTypeArguments);
5984
6078
case SyntaxKind.IntersectionType:
5985
6079
return getTypeFromIntersectionTypeNode(<IntersectionTypeNode>node, aliasSymbol, aliasTypeArguments);
6080
+ case SyntaxKind.PartialType:
6081
+ return getTypeFromPartialTypeNode(<PartialTypeNode>node);
5986
6082
case SyntaxKind.ParenthesizedType:
5987
6083
case SyntaxKind.JSDocNullableType:
5988
6084
case SyntaxKind.JSDocNonNullableType:
@@ -6272,6 +6368,9 @@ namespace ts {
6272
6368
if (type.flags & TypeFlags.IndexedAccess) {
6273
6369
return getIndexedAccessType(instantiateType((<IndexedAccessType>type).objectType, mapper), instantiateType((<IndexedAccessType>type).indexType, mapper));
6274
6370
}
6371
+ if (type.flags & TypeFlags.Partial) {
6372
+ return getPartialType(instantiateType((<PartialType>type).type, mapper));
6373
+ }
6275
6374
}
6276
6375
return type;
6277
6376
}
@@ -6755,6 +6854,17 @@ namespace ts {
6755
6854
6756
6855
if (isSimpleTypeRelatedTo(source, target, relation, reportErrors ? reportError : undefined)) return Ternary.True;
6757
6856
6857
+ // If the target is a 'partial T', the only allowed source is T, partial T, or {}
6858
+ if ((target.flags & (TypeFlags.Partial | TypeFlags.ObjectType)) === TypeFlags.Partial) {
6859
+ if ((source === emptyObjectType) || ((<PartialType>target).type === source)) {
6860
+ return Ternary.True;
6861
+ }
6862
+ if (reportErrors) {
6863
+ reportRelationError(headMessage, source, target);
6864
+ }
6865
+ return Ternary.False;
6866
+ }
6867
+
6758
6868
if (getObjectFlags(source) & ObjectFlags.ObjectLiteral && source.flags & TypeFlags.FreshLiteral) {
6759
6869
if (hasExcessProperties(<FreshObjectLiteralType>source, target, reportErrors)) {
6760
6870
if (reportErrors) {
@@ -15072,6 +15182,10 @@ namespace ts {
15072
15182
getTypeFromIndexedAccessTypeNode(node);
15073
15183
}
15074
15184
15185
+ function checkPartialType(node: PartialTypeNode) {
15186
+ checkSourceElement(node.type);
15187
+ }
15188
+
15075
15189
function isPrivateWithinAmbient(node: Node): boolean {
15076
15190
return (getModifierFlags(node) & ModifierFlags.Private) && isInAmbientContext(node);
15077
15191
}
@@ -18307,6 +18421,8 @@ namespace ts {
18307
18421
case SyntaxKind.UnionType:
18308
18422
case SyntaxKind.IntersectionType:
18309
18423
return checkUnionOrIntersectionType(<UnionOrIntersectionTypeNode>node);
18424
+ case SyntaxKind.PartialType:
18425
+ return checkPartialType(<PartialTypeNode>node);
18310
18426
case SyntaxKind.ParenthesizedType:
18311
18427
case SyntaxKind.TypeOperator:
18312
18428
return checkSourceElement((<ParenthesizedTypeNode | TypeOperatorNode>node).type);
@@ -18662,7 +18778,7 @@ namespace ts {
18662
18778
node = node.parent;
18663
18779
}
18664
18780
18665
- return node.parent && (node.parent.kind === SyntaxKind.TypeReference || node.parent.kind === SyntaxKind.JSDocTypeReference) ;
18781
+ return node.parent && (node.parent.kind === SyntaxKind.TypeReference || node.parent.kind === SyntaxKind.JSDocTypeReference);
18666
18782
}
18667
18783
18668
18784
function isHeritageClauseElementIdentifier(entityName: Node): boolean {
@@ -19054,15 +19170,23 @@ namespace ts {
19054
19170
19055
19171
function getRootSymbols(symbol: Symbol): Symbol[] {
19056
19172
if (symbol.flags & SymbolFlags.SyntheticProperty) {
19057
- const symbols: Symbol[] = [];
19058
- const name = symbol.name;
19059
- forEach(getSymbolLinks(symbol).containingType.types, t => {
19060
- const symbol = getPropertyOfType(t, name);
19061
- if (symbol) {
19062
- symbols.push(symbol);
19063
- }
19064
- });
19065
- return symbols;
19173
+ const links = getSymbolLinks(symbol);
19174
+ if (links.containingType) {
19175
+ const symbols: Symbol[] = [];
19176
+ const name = symbol.name;
19177
+
19178
+ forEach(links.containingType.types, t => {
19179
+ const symbol = getPropertyOfType(t, name);
19180
+ if (symbol) {
19181
+ symbols.push(symbol);
19182
+ }
19183
+ });
19184
+ return symbols;
19185
+ }
19186
+ else if (links.originalType) {
19187
+ return [links.originalType.symbol];
19188
+ }
19189
+ return emptyArray;
19066
19190
}
19067
19191
else if (symbol.flags & SymbolFlags.Transient) {
19068
19192
let target: Symbol;
0 commit comments