@@ -4773,7 +4773,8 @@ namespace ts {
4773
4773
}
4774
4774
const typeParameterNode = typeParameterToDeclarationWithConstraint(getTypeParameterFromMappedType(type), context, appropriateConstraintTypeNode);
4775
4775
const nameTypeNode = type.declaration.nameType ? typeToTypeNodeHelper(getNameTypeFromMappedType(type)!, context) : undefined;
4776
- const templateTypeNode = typeToTypeNodeHelper(getTemplateTypeFromMappedType(type), context);
4776
+ const templateType = getTemplateTypeFromMappedType(type);
4777
+ const templateTypeNode = typeToTypeNodeHelper(getMappedTypeModifiers(type) & MappedTypeModifiers.IncludeOptional ? removeMissingType(templateType) : templateType, context);
4777
4778
const mappedTypeNode = factory.createMappedTypeNode(readonlyToken, typeParameterNode, nameTypeNode, questionToken, templateTypeNode);
4778
4779
context.approximateLength += 10;
4779
4780
return setEmitFlags(mappedTypeNode, EmitFlags.SingleLine);
@@ -4923,7 +4924,7 @@ namespace ts {
4923
4924
}
4924
4925
4925
4926
function typeReferenceToTypeNode(type: TypeReference) {
4926
- const typeArguments: readonly Type[] = getTypeArguments(type);
4927
+ let typeArguments: readonly Type[] = getTypeArguments(type);
4927
4928
if (type.target === globalArrayType || type.target === globalReadonlyArrayType) {
4928
4929
if (context.flags & NodeBuilderFlags.WriteArrayAsGenericType) {
4929
4930
const typeArgumentNode = typeToTypeNodeHelper(typeArguments[0], context);
@@ -4934,6 +4935,7 @@ namespace ts {
4934
4935
return type.target === globalArrayType ? arrayType : factory.createTypeOperatorNode(SyntaxKind.ReadonlyKeyword, arrayType);
4935
4936
}
4936
4937
else if (type.target.objectFlags & ObjectFlags.Tuple) {
4938
+ typeArguments = sameMap(typeArguments, (t, i) => (type.target as TupleType).elementFlags[i] & ElementFlags.Optional ? removeMissingType(t) : t);
4937
4939
if (typeArguments.length > 0) {
4938
4940
const arity = getTypeReferenceArity(type);
4939
4941
const tupleConstituentNodes = mapToTypeNodes(typeArguments.slice(0, arity), context);
@@ -5166,7 +5168,7 @@ namespace ts {
5166
5168
function addPropertyToElementList(propertySymbol: Symbol, context: NodeBuilderContext, typeElements: TypeElement[]) {
5167
5169
const propertyIsReverseMapped = !!(getCheckFlags(propertySymbol) & CheckFlags.ReverseMapped);
5168
5170
const propertyType = shouldUsePlaceholderForProperty(propertySymbol, context) ?
5169
- anyType : getTypeOfSymbol (propertySymbol);
5171
+ anyType : getNonMissingTypeOfSymbol (propertySymbol);
5170
5172
const saveEnclosingDeclaration = context.enclosingDeclaration;
5171
5173
context.enclosingDeclaration = undefined;
5172
5174
if (context.tracker.trackSymbol && getCheckFlags(propertySymbol) & CheckFlags.Late && isLateBoundName(propertySymbol.escapedName)) {
@@ -8608,7 +8610,7 @@ namespace ts {
8608
8610
if (typeNode) {
8609
8611
const annotationSymbol = getPropertyOfType(getTypeFromTypeNode(typeNode), symbol.escapedName);
8610
8612
if (annotationSymbol) {
8611
- return removeMissingType(getTypeOfSymbol(annotationSymbol), annotationSymbol);
8613
+ return getNonMissingTypeOfSymbol( annotationSymbol);
8612
8614
}
8613
8615
}
8614
8616
}
@@ -9314,6 +9316,11 @@ namespace ts {
9314
9316
return errorType;
9315
9317
}
9316
9318
9319
+ function getNonMissingTypeOfSymbol(symbol: Symbol) {
9320
+ const type = getTypeOfSymbol(symbol);
9321
+ return symbol.flags & SymbolFlags.Optional ? removeMissingType(type) : type;
9322
+ }
9323
+
9317
9324
function isReferenceToType(type: Type, target: Type) {
9318
9325
return type !== undefined
9319
9326
&& target !== undefined
@@ -18798,7 +18805,7 @@ namespace ts {
18798
18805
// fixed limit before incurring the cost of any allocations:
18799
18806
let numCombinations = 1;
18800
18807
for (const sourceProperty of sourcePropertiesFiltered) {
18801
- numCombinations *= countTypes(getTypeOfSymbol (sourceProperty));
18808
+ numCombinations *= countTypes(getNonMissingTypeOfSymbol (sourceProperty));
18802
18809
if (numCombinations > 25) {
18803
18810
// We've reached the complexity limit.
18804
18811
tracing?.instant(tracing.Phase.CheckTypes, "typeRelatedToDiscriminatedType_DepthLimit", { sourceId: source.id, targetId: target.id, numCombinations });
@@ -18811,7 +18818,7 @@ namespace ts {
18811
18818
const excludedProperties = new Set<__String>();
18812
18819
for (let i = 0; i < sourcePropertiesFiltered.length; i++) {
18813
18820
const sourceProperty = sourcePropertiesFiltered[i];
18814
- const sourcePropertyType = getTypeOfSymbol (sourceProperty);
18821
+ const sourcePropertyType = getNonMissingTypeOfSymbol (sourceProperty);
18815
18822
sourceDiscriminantTypes[i] = sourcePropertyType.flags & TypeFlags.Union
18816
18823
? (sourcePropertyType as UnionType).types
18817
18824
: [sourcePropertyType];
@@ -18892,8 +18899,8 @@ namespace ts {
18892
18899
18893
18900
function isPropertySymbolTypeRelated(sourceProp: Symbol, targetProp: Symbol, getTypeOfSourceProperty: (sym: Symbol) => Type, reportErrors: boolean, intersectionState: IntersectionState): Ternary {
18894
18901
const targetIsOptional = strictNullChecks && !!(getCheckFlags(targetProp) & CheckFlags.Partial);
18895
- const effectiveTarget = removeMissingType( addOptionality(getTypeOfSymbol (targetProp), /*isProperty*/ false, targetIsOptional), targetProp );
18896
- const effectiveSource = removeMissingType( getTypeOfSourceProperty(sourceProp), sourceProp);
18902
+ const effectiveTarget = addOptionality(getNonMissingTypeOfSymbol (targetProp), /*isProperty*/ false, targetIsOptional);
18903
+ const effectiveSource = getTypeOfSourceProperty(sourceProp);
18897
18904
return isRelatedTo(effectiveSource, effectiveTarget, reportErrors, /*headMessage*/ undefined, intersectionState);
18898
18905
}
18899
18906
@@ -19137,7 +19144,7 @@ namespace ts {
19137
19144
if (!(targetProp.flags & SymbolFlags.Prototype) && (!numericNamesOnly || isNumericLiteralName(name) || name === "length")) {
19138
19145
const sourceProp = getPropertyOfType(source, name);
19139
19146
if (sourceProp && sourceProp !== targetProp) {
19140
- const related = propertyRelatedTo(source, target, sourceProp, targetProp, getTypeOfSymbol , reportErrors, intersectionState, relation === comparableRelation);
19147
+ const related = propertyRelatedTo(source, target, sourceProp, targetProp, getNonMissingTypeOfSymbol , reportErrors, intersectionState, relation === comparableRelation);
19141
19148
if (!related) {
19142
19149
return Ternary.False;
19143
19150
}
@@ -20239,8 +20246,8 @@ namespace ts {
20239
20246
exprType;
20240
20247
}
20241
20248
20242
- function removeMissingType(type: Type, prop: Symbol ) {
20243
- return strictOptionalProperties && prop.flags & SymbolFlags.Optional ? filterType(type, t => t !== missingType) : type;
20249
+ function removeMissingType(type: Type) {
20250
+ return strictOptionalProperties ? filterType(type, t => t !== missingType) : type;
20244
20251
}
20245
20252
20246
20253
function containsMissingType(type: Type) {
@@ -27363,7 +27370,7 @@ namespace ts {
27363
27370
// accessor, or optional method.
27364
27371
const assignmentKind = getAssignmentTargetKind(node);
27365
27372
if (assignmentKind === AssignmentKind.Definite) {
27366
- return prop ? removeMissingType(propType, prop ) : propType;
27373
+ return prop && prop.flags & SymbolFlags.Optional ? removeMissingType(propType) : propType;
27367
27374
}
27368
27375
if (prop &&
27369
27376
!(prop.flags & (SymbolFlags.Variable | SymbolFlags.Property | SymbolFlags.Accessor))
0 commit comments