@@ -249,7 +249,7 @@ namespace ts {
249
249
getTypeOfSymbol,
250
250
getResolvedSymbol,
251
251
getIndexTypeOfStructuredType,
252
- getConstraintFromTypeParameter ,
252
+ getConstraintOfTypeParameter ,
253
253
getFirstIdentifier,
254
254
),
255
255
getAmbientModules,
@@ -3708,7 +3708,7 @@ namespace ts {
3708
3708
return createTypeParameterDeclaration(name, constraintNode, defaultParameterNode);
3709
3709
}
3710
3710
3711
- function typeParameterToDeclaration(type: TypeParameter, context: NodeBuilderContext, constraint = getConstraintFromTypeParameter (type)): TypeParameterDeclaration {
3711
+ function typeParameterToDeclaration(type: TypeParameter, context: NodeBuilderContext, constraint = getConstraintOfTypeParameter (type)): TypeParameterDeclaration {
3712
3712
const constraintNode = constraint && typeToTypeNodeHelper(constraint, context);
3713
3713
return typeParameterToDeclarationWithConstraint(type, context, constraintNode);
3714
3714
}
@@ -4356,29 +4356,23 @@ namespace ts {
4356
4356
return i;
4357
4357
}
4358
4358
}
4359
-
4360
4359
return -1;
4361
4360
}
4362
4361
4363
4362
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;
4372
4374
}
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);
4382
4376
}
4383
4377
4384
4378
// Pop an entry from the type resolution stack and return its associated result value. The result value will
@@ -6971,21 +6965,12 @@ namespace ts {
6971
6965
return undefined;
6972
6966
}
6973
6967
6974
- function getBaseConstraintOfInstantiableNonPrimitiveUnionOrIntersection (type: Type) {
6968
+ function getBaseConstraintOfType (type: Type): Type | undefined {
6975
6969
if (type.flags & (TypeFlags.InstantiableNonPrimitive | TypeFlags.UnionOrIntersection)) {
6976
6970
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;
6987
6972
}
6988
- return constraint ;
6973
+ return type.flags & TypeFlags.Index ? keyofConstraintType : undefined ;
6989
6974
}
6990
6975
6991
6976
/**
@@ -7006,30 +6991,26 @@ namespace ts {
7006
6991
* circularly references the type variable.
7007
6992
*/
7008
6993
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;
7013
7009
}
7014
- return type.resolvedBaseConstraint;
7015
7010
7016
7011
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;
7033
7014
}
7034
7015
7035
7016
function computeBaseConstraint(t: Type): Type | undefined {
@@ -7912,6 +7893,7 @@ namespace ts {
7912
7893
return inferences && getIntersectionType(inferences);
7913
7894
}
7914
7895
7896
+ /** This is a worker function. Use getConstraintOfTypeParameter which guards against circular constraints. */
7915
7897
function getConstraintFromTypeParameter(typeParameter: TypeParameter): Type | undefined {
7916
7898
if (!typeParameter.constraint) {
7917
7899
if (typeParameter.target) {
@@ -9180,7 +9162,7 @@ namespace ts {
9180
9162
return type.simplified = substituteIndexedMappedType(objectType, type);
9181
9163
}
9182
9164
if (objectType.flags & TypeFlags.TypeParameter) {
9183
- const constraint = getConstraintFromTypeParameter (objectType as TypeParameter);
9165
+ const constraint = getConstraintOfTypeParameter (objectType as TypeParameter);
9184
9166
if (constraint && isGenericMappedType(constraint)) {
9185
9167
return type.simplified = substituteIndexedMappedType(constraint, type);
9186
9168
}
@@ -12127,7 +12109,7 @@ namespace ts {
12127
12109
}
12128
12110
12129
12111
function isUnconstrainedTypeParameter(type: Type) {
12130
- return type.flags & TypeFlags.TypeParameter && !getConstraintFromTypeParameter (<TypeParameter>type);
12112
+ return type.flags & TypeFlags.TypeParameter && !getConstraintOfTypeParameter (<TypeParameter>type);
12131
12113
}
12132
12114
12133
12115
function isTypeReferenceWithGenericArguments(type: Type): boolean {
@@ -17656,7 +17638,7 @@ namespace ts {
17656
17638
}
17657
17639
17658
17640
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;
17660
17642
}
17661
17643
// No further restrictions for static properties
17662
17644
if (flags & ModifierFlags.Static) {
@@ -19297,7 +19279,7 @@ namespace ts {
19297
19279
typeArguments.pop();
19298
19280
}
19299
19281
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)));
19301
19283
}
19302
19284
const instantiated = createSignatureInstantiation(candidate, typeArguments);
19303
19285
candidates[bestIndex] = instantiated;
@@ -25202,7 +25184,7 @@ namespace ts {
25202
25184
// If the type parameter node does not have an identical constraint as the resolved
25203
25185
// type parameter at this position, we report an error.
25204
25186
const sourceConstraint = source.constraint && getTypeFromTypeNode(source.constraint);
25205
- const targetConstraint = getConstraintFromTypeParameter (target);
25187
+ const targetConstraint = getConstraintOfTypeParameter (target);
25206
25188
if (sourceConstraint) {
25207
25189
// relax check if later interface augmentation has no constraint
25208
25190
if (!targetConstraint || !isTypeIdenticalTo(sourceConstraint, targetConstraint)) {
0 commit comments