@@ -249,7 +249,7 @@ namespace ts {
249249 getTypeOfSymbol,
250250 getResolvedSymbol,
251251 getIndexTypeOfStructuredType,
252- getConstraintFromTypeParameter ,
252+ getConstraintOfTypeParameter ,
253253 getFirstIdentifier,
254254 ),
255255 getAmbientModules,
@@ -3708,7 +3708,7 @@ namespace ts {
37083708 return createTypeParameterDeclaration(name, constraintNode, defaultParameterNode);
37093709 }
37103710
3711- function typeParameterToDeclaration(type: TypeParameter, context: NodeBuilderContext, constraint = getConstraintFromTypeParameter (type)): TypeParameterDeclaration {
3711+ function typeParameterToDeclaration(type: TypeParameter, context: NodeBuilderContext, constraint = getConstraintOfTypeParameter (type)): TypeParameterDeclaration {
37123712 const constraintNode = constraint && typeToTypeNodeHelper(constraint, context);
37133713 return typeParameterToDeclarationWithConstraint(type, context, constraintNode);
37143714 }
@@ -4356,29 +4356,23 @@ namespace ts {
43564356 return i;
43574357 }
43584358 }
4359-
43604359 return -1;
43614360 }
43624361
43634362 function hasType(target: TypeSystemEntity, propertyName: TypeSystemPropertyName): boolean {
4364- if (propertyName === TypeSystemPropertyName.Type) {
4365- return !!getSymbolLinks(<Symbol>target).type;
4366- }
4367- if (propertyName === TypeSystemPropertyName.DeclaredType) {
4368- return !!getSymbolLinks(<Symbol>target).declaredType;
4369- }
4370- if (propertyName === TypeSystemPropertyName.ResolvedBaseConstructorType) {
4371- return !!(<InterfaceType>target).resolvedBaseConstructorType;
4363+ switch (propertyName) {
4364+ case TypeSystemPropertyName.Type:
4365+ return !!getSymbolLinks(<Symbol>target).type;
4366+ case TypeSystemPropertyName.DeclaredType:
4367+ return !!getSymbolLinks(<Symbol>target).declaredType;
4368+ case TypeSystemPropertyName.ResolvedBaseConstructorType:
4369+ return !!(<InterfaceType>target).resolvedBaseConstructorType;
4370+ case TypeSystemPropertyName.ResolvedReturnType:
4371+ return !!(<Signature>target).resolvedReturnType;
4372+ case TypeSystemPropertyName.ImmediateBaseConstraint:
4373+ return !!(<Type>target).immediateBaseConstraint;
43724374 }
4373- if (propertyName === TypeSystemPropertyName.ResolvedReturnType) {
4374- return !!(<Signature>target).resolvedReturnType;
4375- }
4376- if (propertyName === TypeSystemPropertyName.ImmediateBaseConstraint) {
4377- const bc = (<Type>target).immediateBaseConstraint;
4378- return !!bc && bc !== circularConstraintType;
4379- }
4380-
4381- return Debug.fail("Unhandled TypeSystemPropertyName " + propertyName);
4375+ return Debug.assertNever(propertyName);
43824376 }
43834377
43844378 // Pop an entry from the type resolution stack and return its associated result value. The result value will
@@ -6971,21 +6965,12 @@ namespace ts {
69716965 return undefined;
69726966 }
69736967
6974- function getBaseConstraintOfInstantiableNonPrimitiveUnionOrIntersection (type: Type) {
6968+ function getBaseConstraintOfType (type: Type): Type | undefined {
69756969 if (type.flags & (TypeFlags.InstantiableNonPrimitive | TypeFlags.UnionOrIntersection)) {
69766970 const constraint = getResolvedBaseConstraint(<InstantiableType | UnionOrIntersectionType>type);
6977- if (constraint !== noConstraintType && constraint !== circularConstraintType) {
6978- return constraint;
6979- }
6980- }
6981- }
6982-
6983- function getBaseConstraintOfType(type: Type): Type | undefined {
6984- const constraint = getBaseConstraintOfInstantiableNonPrimitiveUnionOrIntersection(type);
6985- if (!constraint && type.flags & TypeFlags.Index) {
6986- return keyofConstraintType;
6971+ return constraint !== noConstraintType && constraint !== circularConstraintType ? constraint : undefined;
69876972 }
6988- return constraint ;
6973+ return type.flags & TypeFlags.Index ? keyofConstraintType : undefined ;
69896974 }
69906975
69916976 /**
@@ -7006,30 +6991,26 @@ namespace ts {
70066991 * circularly references the type variable.
70076992 */
70086993 function getResolvedBaseConstraint(type: InstantiableType | UnionOrIntersectionType): Type {
7009- let circular: boolean | undefined;
7010- if (!type.resolvedBaseConstraint) {
7011- const constraint = getBaseConstraint(type);
7012- type.resolvedBaseConstraint = circular ? circularConstraintType : getTypeWithThisArgument(constraint || noConstraintType, type);
6994+ return type.resolvedBaseConstraint ||
6995+ (type.resolvedBaseConstraint = getTypeWithThisArgument(getImmediateBaseConstraint(type), type));
6996+
6997+ function getImmediateBaseConstraint(t: Type): Type {
6998+ if (!t.immediateBaseConstraint) {
6999+ if (!pushTypeResolution(t, TypeSystemPropertyName.ImmediateBaseConstraint)) {
7000+ return circularConstraintType;
7001+ }
7002+ let result = computeBaseConstraint(getSimplifiedType(t));
7003+ if (!popTypeResolution()) {
7004+ result = circularConstraintType;
7005+ }
7006+ t.immediateBaseConstraint = result || noConstraintType;
7007+ }
7008+ return t.immediateBaseConstraint;
70137009 }
7014- return type.resolvedBaseConstraint;
70157010
70167011 function getBaseConstraint(t: Type): Type | undefined {
7017- if (t.immediateBaseConstraint) {
7018- return t.immediateBaseConstraint === noConstraintType ? undefined : t.immediateBaseConstraint;
7019- }
7020- if (!pushTypeResolution(t, TypeSystemPropertyName.ImmediateBaseConstraint)) {
7021- circular = true;
7022- t.immediateBaseConstraint = circularConstraintType;
7023- return undefined;
7024- }
7025- const result = computeBaseConstraint(getSimplifiedType(t));
7026- if (!popTypeResolution()) {
7027- circular = true;
7028- t.immediateBaseConstraint = circularConstraintType;
7029- return undefined;
7030- }
7031- t.immediateBaseConstraint = !result ? noConstraintType : result;
7032- return result;
7012+ const c = getImmediateBaseConstraint(t);
7013+ return c !== noConstraintType && c !== circularConstraintType ? c : undefined;
70337014 }
70347015
70357016 function computeBaseConstraint(t: Type): Type | undefined {
@@ -7912,6 +7893,7 @@ namespace ts {
79127893 return inferences && getIntersectionType(inferences);
79137894 }
79147895
7896+ /** This is a worker function. Use getConstraintOfTypeParameter which guards against circular constraints. */
79157897 function getConstraintFromTypeParameter(typeParameter: TypeParameter): Type | undefined {
79167898 if (!typeParameter.constraint) {
79177899 if (typeParameter.target) {
@@ -9180,7 +9162,7 @@ namespace ts {
91809162 return type.simplified = substituteIndexedMappedType(objectType, type);
91819163 }
91829164 if (objectType.flags & TypeFlags.TypeParameter) {
9183- const constraint = getConstraintFromTypeParameter (objectType as TypeParameter);
9165+ const constraint = getConstraintOfTypeParameter (objectType as TypeParameter);
91849166 if (constraint && isGenericMappedType(constraint)) {
91859167 return type.simplified = substituteIndexedMappedType(constraint, type);
91869168 }
@@ -12127,7 +12109,7 @@ namespace ts {
1212712109 }
1212812110
1212912111 function isUnconstrainedTypeParameter(type: Type) {
12130- return type.flags & TypeFlags.TypeParameter && !getConstraintFromTypeParameter (<TypeParameter>type);
12112+ return type.flags & TypeFlags.TypeParameter && !getConstraintOfTypeParameter (<TypeParameter>type);
1213112113 }
1213212114
1213312115 function isTypeReferenceWithGenericArguments(type: Type): boolean {
@@ -17656,7 +17638,7 @@ namespace ts {
1765617638 }
1765717639
1765817640 const thisType = getTypeFromTypeNode(thisParameter.type);
17659- enclosingClass = ((thisType.flags & TypeFlags.TypeParameter) ? getConstraintFromTypeParameter (<TypeParameter>thisType) : thisType) as InterfaceType;
17641+ enclosingClass = ((thisType.flags & TypeFlags.TypeParameter) ? getConstraintOfTypeParameter (<TypeParameter>thisType) : thisType) as InterfaceType;
1766017642 }
1766117643 // No further restrictions for static properties
1766217644 if (flags & ModifierFlags.Static) {
@@ -19297,7 +19279,7 @@ namespace ts {
1929719279 typeArguments.pop();
1929819280 }
1929919281 while (typeArguments.length < typeParameters.length) {
19300- typeArguments.push(getConstraintFromTypeParameter (typeParameters[typeArguments.length]) || getDefaultTypeArgumentType(isInJavaScriptFile(node)));
19282+ typeArguments.push(getConstraintOfTypeParameter (typeParameters[typeArguments.length]) || getDefaultTypeArgumentType(isInJavaScriptFile(node)));
1930119283 }
1930219284 const instantiated = createSignatureInstantiation(candidate, typeArguments);
1930319285 candidates[bestIndex] = instantiated;
@@ -25202,7 +25184,7 @@ namespace ts {
2520225184 // If the type parameter node does not have an identical constraint as the resolved
2520325185 // type parameter at this position, we report an error.
2520425186 const sourceConstraint = source.constraint && getTypeFromTypeNode(source.constraint);
25205- const targetConstraint = getConstraintFromTypeParameter (target);
25187+ const targetConstraint = getConstraintOfTypeParameter (target);
2520625188 if (sourceConstraint) {
2520725189 // relax check if later interface augmentation has no constraint
2520825190 if (!targetConstraint || !isTypeIdenticalTo(sourceConstraint, targetConstraint)) {
0 commit comments