@@ -250,7 +250,7 @@ namespace ts {
250
250
getTypeOfSymbol,
251
251
getResolvedSymbol,
252
252
getIndexTypeOfStructuredType,
253
- getConstraintFromTypeParameter ,
253
+ getConstraintOfTypeParameter ,
254
254
getFirstIdentifier,
255
255
),
256
256
getAmbientModules,
@@ -3715,7 +3715,7 @@ namespace ts {
3715
3715
return createTypeParameterDeclaration(name, constraintNode, defaultParameterNode);
3716
3716
}
3717
3717
3718
- function typeParameterToDeclaration(type: TypeParameter, context: NodeBuilderContext, constraint = getConstraintFromTypeParameter (type)): TypeParameterDeclaration {
3718
+ function typeParameterToDeclaration(type: TypeParameter, context: NodeBuilderContext, constraint = getConstraintOfTypeParameter (type)): TypeParameterDeclaration {
3719
3719
const constraintNode = constraint && typeToTypeNodeHelper(constraint, context);
3720
3720
return typeParameterToDeclarationWithConstraint(type, context, constraintNode);
3721
3721
}
@@ -4363,29 +4363,23 @@ namespace ts {
4363
4363
return i;
4364
4364
}
4365
4365
}
4366
-
4367
4366
return -1;
4368
4367
}
4369
4368
4370
4369
function hasType(target: TypeSystemEntity, propertyName: TypeSystemPropertyName): boolean {
4371
- if (propertyName === TypeSystemPropertyName.Type) {
4372
- return !!getSymbolLinks(<Symbol>target).type;
4373
- }
4374
- if (propertyName === TypeSystemPropertyName.DeclaredType) {
4375
- return !!getSymbolLinks(<Symbol>target).declaredType;
4376
- }
4377
- if (propertyName === TypeSystemPropertyName.ResolvedBaseConstructorType) {
4378
- return !!(<InterfaceType>target).resolvedBaseConstructorType;
4370
+ switch (propertyName) {
4371
+ case TypeSystemPropertyName.Type:
4372
+ return !!getSymbolLinks(<Symbol>target).type;
4373
+ case TypeSystemPropertyName.DeclaredType:
4374
+ return !!getSymbolLinks(<Symbol>target).declaredType;
4375
+ case TypeSystemPropertyName.ResolvedBaseConstructorType:
4376
+ return !!(<InterfaceType>target).resolvedBaseConstructorType;
4377
+ case TypeSystemPropertyName.ResolvedReturnType:
4378
+ return !!(<Signature>target).resolvedReturnType;
4379
+ case TypeSystemPropertyName.ImmediateBaseConstraint:
4380
+ return !!(<Type>target).immediateBaseConstraint;
4379
4381
}
4380
- if (propertyName === TypeSystemPropertyName.ResolvedReturnType) {
4381
- return !!(<Signature>target).resolvedReturnType;
4382
- }
4383
- if (propertyName === TypeSystemPropertyName.ImmediateBaseConstraint) {
4384
- const bc = (<Type>target).immediateBaseConstraint;
4385
- return !!bc && bc !== circularConstraintType;
4386
- }
4387
-
4388
- return Debug.fail("Unhandled TypeSystemPropertyName " + propertyName);
4382
+ return Debug.assertNever(propertyName);
4389
4383
}
4390
4384
4391
4385
// Pop an entry from the type resolution stack and return its associated result value. The result value will
@@ -6936,21 +6930,12 @@ namespace ts {
6936
6930
return undefined;
6937
6931
}
6938
6932
6939
- function getBaseConstraintOfInstantiableNonPrimitiveUnionOrIntersection (type: Type) {
6933
+ function getBaseConstraintOfType (type: Type): Type | undefined {
6940
6934
if (type.flags & (TypeFlags.InstantiableNonPrimitive | TypeFlags.UnionOrIntersection)) {
6941
6935
const constraint = getResolvedBaseConstraint(<InstantiableType | UnionOrIntersectionType>type);
6942
- if (constraint !== noConstraintType && constraint !== circularConstraintType) {
6943
- return constraint;
6944
- }
6945
- }
6946
- }
6947
-
6948
- function getBaseConstraintOfType(type: Type): Type | undefined {
6949
- const constraint = getBaseConstraintOfInstantiableNonPrimitiveUnionOrIntersection(type);
6950
- if (!constraint && type.flags & TypeFlags.Index) {
6951
- return keyofConstraintType;
6936
+ return constraint !== noConstraintType && constraint !== circularConstraintType ? constraint : undefined;
6952
6937
}
6953
- return constraint ;
6938
+ return type.flags & TypeFlags.Index ? keyofConstraintType : undefined ;
6954
6939
}
6955
6940
6956
6941
/**
@@ -6971,30 +6956,26 @@ namespace ts {
6971
6956
* circularly references the type variable.
6972
6957
*/
6973
6958
function getResolvedBaseConstraint(type: InstantiableType | UnionOrIntersectionType): Type {
6974
- let circular: boolean | undefined;
6975
- if (!type.resolvedBaseConstraint) {
6976
- const constraint = getBaseConstraint(type);
6977
- type.resolvedBaseConstraint = circular ? circularConstraintType : getTypeWithThisArgument(constraint || noConstraintType, type);
6959
+ return type.resolvedBaseConstraint ||
6960
+ (type.resolvedBaseConstraint = getTypeWithThisArgument(getImmediateBaseConstraint(type), type));
6961
+
6962
+ function getImmediateBaseConstraint(t: Type): Type {
6963
+ if (!t.immediateBaseConstraint) {
6964
+ if (!pushTypeResolution(t, TypeSystemPropertyName.ImmediateBaseConstraint)) {
6965
+ return circularConstraintType;
6966
+ }
6967
+ let result = computeBaseConstraint(getSimplifiedType(t));
6968
+ if (!popTypeResolution()) {
6969
+ result = circularConstraintType;
6970
+ }
6971
+ t.immediateBaseConstraint = result || noConstraintType;
6972
+ }
6973
+ return t.immediateBaseConstraint;
6978
6974
}
6979
- return type.resolvedBaseConstraint;
6980
6975
6981
6976
function getBaseConstraint(t: Type): Type | undefined {
6982
- if (t.immediateBaseConstraint) {
6983
- return t.immediateBaseConstraint === noConstraintType ? undefined : t.immediateBaseConstraint;
6984
- }
6985
- if (!pushTypeResolution(t, TypeSystemPropertyName.ImmediateBaseConstraint)) {
6986
- circular = true;
6987
- t.immediateBaseConstraint = circularConstraintType;
6988
- return undefined;
6989
- }
6990
- const result = computeBaseConstraint(getSimplifiedType(t));
6991
- if (!popTypeResolution()) {
6992
- circular = true;
6993
- t.immediateBaseConstraint = circularConstraintType;
6994
- return undefined;
6995
- }
6996
- t.immediateBaseConstraint = !result ? noConstraintType : result;
6997
- return result;
6977
+ const c = getImmediateBaseConstraint(t);
6978
+ return c !== noConstraintType && c !== circularConstraintType ? c : undefined;
6998
6979
}
6999
6980
7000
6981
function computeBaseConstraint(t: Type): Type | undefined {
@@ -7877,6 +7858,7 @@ namespace ts {
7877
7858
return inferences && getIntersectionType(inferences);
7878
7859
}
7879
7860
7861
+ /** This is a worker function. Use getConstraintOfTypeParameter which guards against circular constraints. */
7880
7862
function getConstraintFromTypeParameter(typeParameter: TypeParameter): Type | undefined {
7881
7863
if (!typeParameter.constraint) {
7882
7864
if (typeParameter.target) {
@@ -9145,7 +9127,7 @@ namespace ts {
9145
9127
return type.simplified = substituteIndexedMappedType(objectType, type);
9146
9128
}
9147
9129
if (objectType.flags & TypeFlags.TypeParameter) {
9148
- const constraint = getConstraintFromTypeParameter (objectType as TypeParameter);
9130
+ const constraint = getConstraintOfTypeParameter (objectType as TypeParameter);
9149
9131
if (constraint && isGenericMappedType(constraint)) {
9150
9132
return type.simplified = substituteIndexedMappedType(constraint, type);
9151
9133
}
@@ -12092,7 +12074,7 @@ namespace ts {
12092
12074
}
12093
12075
12094
12076
function isUnconstrainedTypeParameter(type: Type) {
12095
- return type.flags & TypeFlags.TypeParameter && !getConstraintFromTypeParameter (<TypeParameter>type);
12077
+ return type.flags & TypeFlags.TypeParameter && !getConstraintOfTypeParameter (<TypeParameter>type);
12096
12078
}
12097
12079
12098
12080
function isTypeReferenceWithGenericArguments(type: Type): boolean {
@@ -17620,7 +17602,7 @@ namespace ts {
17620
17602
}
17621
17603
17622
17604
const thisType = getTypeFromTypeNode(thisParameter.type);
17623
- enclosingClass = ((thisType.flags & TypeFlags.TypeParameter) ? getConstraintFromTypeParameter (<TypeParameter>thisType) : thisType) as InterfaceType;
17605
+ enclosingClass = ((thisType.flags & TypeFlags.TypeParameter) ? getConstraintOfTypeParameter (<TypeParameter>thisType) : thisType) as InterfaceType;
17624
17606
}
17625
17607
// No further restrictions for static properties
17626
17608
if (flags & ModifierFlags.Static) {
@@ -19261,7 +19243,7 @@ namespace ts {
19261
19243
typeArguments.pop();
19262
19244
}
19263
19245
while (typeArguments.length < typeParameters.length) {
19264
- typeArguments.push(getConstraintFromTypeParameter (typeParameters[typeArguments.length]) || getDefaultTypeArgumentType(isInJavaScriptFile(node)));
19246
+ typeArguments.push(getConstraintOfTypeParameter (typeParameters[typeArguments.length]) || getDefaultTypeArgumentType(isInJavaScriptFile(node)));
19265
19247
}
19266
19248
const instantiated = createSignatureInstantiation(candidate, typeArguments);
19267
19249
candidates[bestIndex] = instantiated;
@@ -25164,7 +25146,7 @@ namespace ts {
25164
25146
// If the type parameter node does not have an identical constraint as the resolved
25165
25147
// type parameter at this position, we report an error.
25166
25148
const sourceConstraint = source.constraint && getTypeFromTypeNode(source.constraint);
25167
- const targetConstraint = getConstraintFromTypeParameter (target);
25149
+ const targetConstraint = getConstraintOfTypeParameter (target);
25168
25150
if (sourceConstraint) {
25169
25151
// relax check if later interface augmentation has no constraint
25170
25152
if (!targetConstraint || !isTypeIdenticalTo(sourceConstraint, targetConstraint)) {
0 commit comments