Skip to content

Commit ad0239a

Browse files
committed
Removing missingType when printing back optional properties
1 parent c3d8482 commit ad0239a

File tree

1 file changed

+19
-12
lines changed

1 file changed

+19
-12
lines changed

src/compiler/checker.ts

Lines changed: 19 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4773,7 +4773,8 @@ namespace ts {
47734773
}
47744774
const typeParameterNode = typeParameterToDeclarationWithConstraint(getTypeParameterFromMappedType(type), context, appropriateConstraintTypeNode);
47754775
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);
47774778
const mappedTypeNode = factory.createMappedTypeNode(readonlyToken, typeParameterNode, nameTypeNode, questionToken, templateTypeNode);
47784779
context.approximateLength += 10;
47794780
return setEmitFlags(mappedTypeNode, EmitFlags.SingleLine);
@@ -4923,7 +4924,7 @@ namespace ts {
49234924
}
49244925

49254926
function typeReferenceToTypeNode(type: TypeReference) {
4926-
const typeArguments: readonly Type[] = getTypeArguments(type);
4927+
let typeArguments: readonly Type[] = getTypeArguments(type);
49274928
if (type.target === globalArrayType || type.target === globalReadonlyArrayType) {
49284929
if (context.flags & NodeBuilderFlags.WriteArrayAsGenericType) {
49294930
const typeArgumentNode = typeToTypeNodeHelper(typeArguments[0], context);
@@ -4934,6 +4935,7 @@ namespace ts {
49344935
return type.target === globalArrayType ? arrayType : factory.createTypeOperatorNode(SyntaxKind.ReadonlyKeyword, arrayType);
49354936
}
49364937
else if (type.target.objectFlags & ObjectFlags.Tuple) {
4938+
typeArguments = sameMap(typeArguments, (t, i) => (type.target as TupleType).elementFlags[i] & ElementFlags.Optional ? removeMissingType(t) : t);
49374939
if (typeArguments.length > 0) {
49384940
const arity = getTypeReferenceArity(type);
49394941
const tupleConstituentNodes = mapToTypeNodes(typeArguments.slice(0, arity), context);
@@ -5166,7 +5168,7 @@ namespace ts {
51665168
function addPropertyToElementList(propertySymbol: Symbol, context: NodeBuilderContext, typeElements: TypeElement[]) {
51675169
const propertyIsReverseMapped = !!(getCheckFlags(propertySymbol) & CheckFlags.ReverseMapped);
51685170
const propertyType = shouldUsePlaceholderForProperty(propertySymbol, context) ?
5169-
anyType : getTypeOfSymbol(propertySymbol);
5171+
anyType : getNonMissingTypeOfSymbol(propertySymbol);
51705172
const saveEnclosingDeclaration = context.enclosingDeclaration;
51715173
context.enclosingDeclaration = undefined;
51725174
if (context.tracker.trackSymbol && getCheckFlags(propertySymbol) & CheckFlags.Late && isLateBoundName(propertySymbol.escapedName)) {
@@ -8608,7 +8610,7 @@ namespace ts {
86088610
if (typeNode) {
86098611
const annotationSymbol = getPropertyOfType(getTypeFromTypeNode(typeNode), symbol.escapedName);
86108612
if (annotationSymbol) {
8611-
return removeMissingType(getTypeOfSymbol(annotationSymbol), annotationSymbol);
8613+
return getNonMissingTypeOfSymbol(annotationSymbol);
86128614
}
86138615
}
86148616
}
@@ -9314,6 +9316,11 @@ namespace ts {
93149316
return errorType;
93159317
}
93169318

9319+
function getNonMissingTypeOfSymbol(symbol: Symbol) {
9320+
const type = getTypeOfSymbol(symbol);
9321+
return symbol.flags & SymbolFlags.Optional ? removeMissingType(type) : type;
9322+
}
9323+
93179324
function isReferenceToType(type: Type, target: Type) {
93189325
return type !== undefined
93199326
&& target !== undefined
@@ -18798,7 +18805,7 @@ namespace ts {
1879818805
// fixed limit before incurring the cost of any allocations:
1879918806
let numCombinations = 1;
1880018807
for (const sourceProperty of sourcePropertiesFiltered) {
18801-
numCombinations *= countTypes(getTypeOfSymbol(sourceProperty));
18808+
numCombinations *= countTypes(getNonMissingTypeOfSymbol(sourceProperty));
1880218809
if (numCombinations > 25) {
1880318810
// We've reached the complexity limit.
1880418811
tracing?.instant(tracing.Phase.CheckTypes, "typeRelatedToDiscriminatedType_DepthLimit", { sourceId: source.id, targetId: target.id, numCombinations });
@@ -18811,7 +18818,7 @@ namespace ts {
1881118818
const excludedProperties = new Set<__String>();
1881218819
for (let i = 0; i < sourcePropertiesFiltered.length; i++) {
1881318820
const sourceProperty = sourcePropertiesFiltered[i];
18814-
const sourcePropertyType = getTypeOfSymbol(sourceProperty);
18821+
const sourcePropertyType = getNonMissingTypeOfSymbol(sourceProperty);
1881518822
sourceDiscriminantTypes[i] = sourcePropertyType.flags & TypeFlags.Union
1881618823
? (sourcePropertyType as UnionType).types
1881718824
: [sourcePropertyType];
@@ -18892,8 +18899,8 @@ namespace ts {
1889218899

1889318900
function isPropertySymbolTypeRelated(sourceProp: Symbol, targetProp: Symbol, getTypeOfSourceProperty: (sym: Symbol) => Type, reportErrors: boolean, intersectionState: IntersectionState): Ternary {
1889418901
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);
1889718904
return isRelatedTo(effectiveSource, effectiveTarget, reportErrors, /*headMessage*/ undefined, intersectionState);
1889818905
}
1889918906

@@ -19137,7 +19144,7 @@ namespace ts {
1913719144
if (!(targetProp.flags & SymbolFlags.Prototype) && (!numericNamesOnly || isNumericLiteralName(name) || name === "length")) {
1913819145
const sourceProp = getPropertyOfType(source, name);
1913919146
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);
1914119148
if (!related) {
1914219149
return Ternary.False;
1914319150
}
@@ -20239,8 +20246,8 @@ namespace ts {
2023920246
exprType;
2024020247
}
2024120248

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;
2024420251
}
2024520252

2024620253
function containsMissingType(type: Type) {
@@ -27363,7 +27370,7 @@ namespace ts {
2736327370
// accessor, or optional method.
2736427371
const assignmentKind = getAssignmentTargetKind(node);
2736527372
if (assignmentKind === AssignmentKind.Definite) {
27366-
return prop ? removeMissingType(propType, prop) : propType;
27373+
return prop && prop.flags & SymbolFlags.Optional ? removeMissingType(propType) : propType;
2736727374
}
2736827375
if (prop &&
2736927376
!(prop.flags & (SymbolFlags.Variable | SymbolFlags.Property | SymbolFlags.Accessor))

0 commit comments

Comments
 (0)