From 205653adde9dfe9ab57fe71a9e557b19bf03b03c Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Tue, 24 Jul 2018 06:19:58 -0700 Subject: [PATCH] Consistently include circularity check in type parameter constraints --- src/compiler/checker.ts | 41 ++++++++++++++++++----------------------- 1 file changed, 18 insertions(+), 23 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index f1e282845d5..7cdc083874f 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -3715,7 +3715,7 @@ namespace ts { return createTypeParameterDeclaration(name, constraintNode, defaultParameterNode); } - function typeParameterToDeclaration(type: TypeParameter, context: NodeBuilderContext, constraint = getConstraintFromTypeParameter(type)): TypeParameterDeclaration { + function typeParameterToDeclaration(type: TypeParameter, context: NodeBuilderContext, constraint = getConstraintOfTypeParameter(type)): TypeParameterDeclaration { const constraintNode = constraint && typeToTypeNodeHelper(constraint, context); return typeParameterToDeclarationWithConstraint(type, context, constraintNode); } @@ -4363,28 +4363,23 @@ namespace ts { return i; } } - return -1; } function hasType(target: TypeSystemEntity, propertyName: TypeSystemPropertyName): boolean { - if (propertyName === TypeSystemPropertyName.Type) { - return !!getSymbolLinks(target).type; + switch (propertyName) { + case TypeSystemPropertyName.Type: + return !!getSymbolLinks(target).type; + case TypeSystemPropertyName.DeclaredType: + return !!getSymbolLinks(target).declaredType; + case TypeSystemPropertyName.ResolvedBaseConstructorType: + return !!(target).resolvedBaseConstructorType; + case TypeSystemPropertyName.ResolvedReturnType: + return !!(target).resolvedReturnType; + case TypeSystemPropertyName.ImmediateBaseConstraint: + const bc = (target).immediateBaseConstraint; + return !!bc && bc !== circularConstraintType; } - if (propertyName === TypeSystemPropertyName.DeclaredType) { - return !!getSymbolLinks(target).declaredType; - } - if (propertyName === TypeSystemPropertyName.ResolvedBaseConstructorType) { - return !!(target).resolvedBaseConstructorType; - } - if (propertyName === TypeSystemPropertyName.ResolvedReturnType) { - return !!(target).resolvedReturnType; - } - if (propertyName === TypeSystemPropertyName.ImmediateBaseConstraint) { - const bc = (target).immediateBaseConstraint; - return !!bc && bc !== circularConstraintType; - } - return Debug.fail("Unhandled TypeSystemPropertyName " + propertyName); } @@ -9145,7 +9140,7 @@ namespace ts { return type.simplified = substituteIndexedMappedType(objectType, type); } if (objectType.flags & TypeFlags.TypeParameter) { - const constraint = getConstraintFromTypeParameter(objectType as TypeParameter); + const constraint = getConstraintOfTypeParameter(objectType as TypeParameter); if (constraint && isGenericMappedType(constraint)) { return type.simplified = substituteIndexedMappedType(constraint, type); } @@ -12092,7 +12087,7 @@ namespace ts { } function isUnconstrainedTypeParameter(type: Type) { - return type.flags & TypeFlags.TypeParameter && !getConstraintFromTypeParameter(type); + return type.flags & TypeFlags.TypeParameter && !getConstraintOfTypeParameter(type); } function isTypeReferenceWithGenericArguments(type: Type): boolean { @@ -17620,7 +17615,7 @@ namespace ts { } const thisType = getTypeFromTypeNode(thisParameter.type); - enclosingClass = ((thisType.flags & TypeFlags.TypeParameter) ? getConstraintFromTypeParameter(thisType) : thisType) as InterfaceType; + enclosingClass = ((thisType.flags & TypeFlags.TypeParameter) ? getConstraintOfTypeParameter(thisType) : thisType) as InterfaceType; } // No further restrictions for static properties if (flags & ModifierFlags.Static) { @@ -19261,7 +19256,7 @@ namespace ts { typeArguments.pop(); } while (typeArguments.length < typeParameters.length) { - typeArguments.push(getConstraintFromTypeParameter(typeParameters[typeArguments.length]) || getDefaultTypeArgumentType(isInJavaScriptFile(node))); + typeArguments.push(getConstraintOfTypeParameter(typeParameters[typeArguments.length]) || getDefaultTypeArgumentType(isInJavaScriptFile(node))); } const instantiated = createSignatureInstantiation(candidate, typeArguments); candidates[bestIndex] = instantiated; @@ -25164,7 +25159,7 @@ namespace ts { // If the type parameter node does not have an identical constraint as the resolved // type parameter at this position, we report an error. const sourceConstraint = source.constraint && getTypeFromTypeNode(source.constraint); - const targetConstraint = getConstraintFromTypeParameter(target); + const targetConstraint = getConstraintOfTypeParameter(target); if (sourceConstraint) { // relax check if later interface augmentation has no constraint if (!targetConstraint || !isTypeIdenticalTo(sourceConstraint, targetConstraint)) {