Skip to content

Commit 4c7ec3c

Browse files
committed
Shared code path for getConditionalType and instantiateConditionalType
1 parent b869290 commit 4c7ec3c

1 file changed

Lines changed: 23 additions & 34 deletions

File tree

src/compiler/checker.ts

Lines changed: 23 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -8091,26 +8091,38 @@ namespace ts {
80918091
return type;
80928092
}
80938093

8094-
function getConditionalType(checkType: Type, extendsType: Type, trueType: Type, falseType: Type, aliasSymbol?: Symbol, aliasTypeArguments?: Type[]): Type {
8094+
function getConditionalType(checkType: Type, extendsType: Type, baseTrueType: Type, baseFalseType: Type, target: ConditionalType, mapper: TypeMapper, aliasSymbol?: Symbol, baseAliasTypeArguments?: Type[]): Type {
80958095
// Distribute union types over conditional types
80968096
if (checkType.flags & TypeFlags.Union) {
8097-
return getUnionType(map((<UnionType>checkType).types, t => getConditionalType(t, extendsType, trueType, falseType)));
8097+
return getUnionType(map((<UnionType>checkType).types, t => getConditionalType(t, extendsType, baseTrueType, baseFalseType, target, mapper)));
80988098
}
80998099
// Return union of trueType and falseType for any and never since they match anything
81008100
if (checkType.flags & (TypeFlags.Any | TypeFlags.Never)) {
8101-
return getUnionType([trueType, falseType]);
8101+
return getUnionType([instantiateType(baseTrueType, mapper), instantiateType(baseFalseType, mapper)]);
81028102
}
81038103
// Return trueType for a definitely true extends check
81048104
if (isTypeAssignableTo(checkType, extendsType)) {
8105-
return trueType;
8105+
return instantiateType(baseTrueType, mapper);
81068106
}
81078107
// Return falseType for a definitely false extends check
81088108
if (!typeMaybeAssignableTo(instantiateType(checkType, anyMapper), instantiateType(extendsType, constraintMapper))) {
8109-
return falseType;
8109+
return instantiateType(baseFalseType, mapper);
81108110
}
81118111
// Return a deferred type for a check that is neither definitely true nor definitely false
8112-
return createConditionalType(getActualTypeParameter(checkType), extendsType, trueType, falseType,
8113-
/*target*/ undefined, /*mapper*/ undefined, aliasSymbol, aliasTypeArguments);
8112+
const erasedCheckType = getActualTypeParameter(checkType);
8113+
const trueType = instantiateType(baseTrueType, mapper);
8114+
const falseType = instantiateType(baseFalseType, mapper);
8115+
const id = target && (target.id + "," + erasedCheckType.id + "," + extendsType.id + "," + trueType.id + "," + falseType.id);
8116+
const cached = id && conditionalTypes.get(id);
8117+
if (cached) {
8118+
return cached;
8119+
}
8120+
const result = createConditionalType(erasedCheckType, extendsType, trueType, falseType,
8121+
target, mapper, aliasSymbol, instantiateTypes(baseAliasTypeArguments, mapper));
8122+
if (id) {
8123+
conditionalTypes.set(id, result);
8124+
}
8125+
return result;
81148126
}
81158127

81168128
function getTypeFromConditionalTypeNode(node: ConditionalTypeNode): Type {
@@ -8119,6 +8131,7 @@ namespace ts {
81198131
links.resolvedType = getConditionalType(
81208132
getTypeFromTypeNode(node.checkType), getTypeFromTypeNode(node.extendsType),
81218133
getTypeFromTypeNode(node.trueType), getTypeFromTypeNode(node.falseType),
8134+
/*target*/ undefined, /*mapper*/ undefined,
81228135
getAliasSymbolForTypeNode(node), getAliasTypeArgumentsForTypeNode(node));
81238136
}
81248137
return links.resolvedType;
@@ -8705,36 +8718,12 @@ namespace ts {
87058718
}
87068719

87078720
function instantiateConditionalType(type: ConditionalType, mapper: TypeMapper): Type {
8708-
const checkType = instantiateType(type.checkType, mapper);
8709-
// Return union of trueType and falseType for any and never since they match anything
8710-
if (checkType.flags & (TypeFlags.Any | TypeFlags.Never)) {
8711-
return getUnionType([instantiateType(type.trueType, mapper), instantiateType(type.falseType, mapper)]);
8712-
}
8713-
const extendsType = instantiateType(type.extendsType, mapper);
8714-
// Return trueType for a definitely true extends check
8715-
if (isTypeAssignableTo(checkType, extendsType)) {
8716-
return instantiateType(type.trueType, mapper);
8717-
}
8718-
// Return falseType for a definitely false extends check
8719-
if (!typeMaybeAssignableTo(instantiateType(checkType, anyMapper), instantiateType(extendsType, constraintMapper))) {
8720-
return instantiateType(type.falseType, mapper);
8721-
}
8722-
// Return a deferred type for a check that is neither definitely true nor definitely false
8723-
const erasedCheckType = getActualTypeParameter(checkType);
8724-
const trueType = instantiateType(type.trueType, mapper);
8725-
const falseType = instantiateType(type.falseType, mapper);
8726-
const id = type.id + "," + erasedCheckType.id + "," + extendsType.id + "," + trueType.id + "," + falseType.id;
8727-
let result = conditionalTypes.get(id);
8728-
if (!result) {
8729-
result = createConditionalType(erasedCheckType, extendsType, trueType, falseType,
8730-
type, mapper, type.aliasSymbol, instantiateTypes(type.aliasTypeArguments, mapper));
8731-
conditionalTypes.set(id, result);
8732-
}
8733-
return result;
8721+
return getConditionalType(instantiateType(type.checkType, mapper), instantiateType(type.extendsType, mapper),
8722+
type.trueType, type.falseType, type, mapper, type.aliasSymbol, type.aliasTypeArguments);
87348723
}
87358724

87368725
function instantiateType(type: Type, mapper: TypeMapper): Type {
8737-
if (type && mapper !== identityMapper) {
8726+
if (type && mapper && mapper !== identityMapper) {
87388727
if (type.flags & TypeFlags.TypeParameter) {
87398728
return mapper(<TypeParameter>type);
87408729
}

0 commit comments

Comments
 (0)