@@ -1016,7 +1016,18 @@ namespace ts {
10161016 }
10171017 }
10181018 break;
1019-
1019+ case SyntaxKind.ExpressionWithTypeArguments:
1020+ // The type parameters of a class are not in scope in the base class expression.
1021+ if (lastLocation === (<ExpressionWithTypeArguments>location).expression && (<HeritageClause>location.parent).token === SyntaxKind.ExtendsKeyword) {
1022+ const container = location.parent.parent;
1023+ if (isClassLike(container) && (result = lookup(getSymbolOfNode(container).members, name, meaning & SymbolFlags.Type))) {
1024+ if (nameNotFoundMessage) {
1025+ error(errorLocation, Diagnostics.Base_class_expressions_cannot_reference_class_type_parameters);
1026+ }
1027+ return undefined;
1028+ }
1029+ }
1030+ break;
10201031 // It is not legal to reference a class's own type parameters from a computed property name that
10211032 // belongs to the class. For example:
10221033 //
@@ -4929,7 +4940,7 @@ namespace ts {
49294940 }
49304941
49314942 function resolveBaseTypesOfClass(type: InterfaceType): void {
4932- type.resolvedBaseTypes = type.resolvedBaseTypes || emptyArray;
4943+ type.resolvedBaseTypes = emptyArray;
49334944 const baseConstructorType = getApparentType(getBaseConstructorTypeOfClass(type));
49344945 if (!(baseConstructorType.flags & (TypeFlags.Object | TypeFlags.Intersection | TypeFlags.Any))) {
49354946 return;
@@ -4976,17 +4987,12 @@ namespace ts {
49764987 error(baseTypeNode.expression, Diagnostics.Base_constructor_return_type_0_is_not_a_class_or_interface_type, typeToString(baseType));
49774988 return;
49784989 }
4979- if (type === baseType || hasBaseType(<BaseType> baseType, type)) {
4990+ if (type === baseType || hasBaseType(baseType, type)) {
49804991 error(valueDecl, Diagnostics.Type_0_recursively_references_itself_as_a_base_type,
49814992 typeToString(type, /*enclosingDeclaration*/ undefined, TypeFormatFlags.WriteArrayAsGenericType));
49824993 return;
49834994 }
4984- if (type.resolvedBaseTypes === emptyArray) {
4985- type.resolvedBaseTypes = [<ObjectType>baseType];
4986- }
4987- else {
4988- type.resolvedBaseTypes.push(<ObjectType>baseType);
4989- }
4995+ type.resolvedBaseTypes = [baseType];
49904996 }
49914997
49924998 function areAllOuterTypeParametersApplied(type: Type): boolean {
@@ -5003,7 +5009,7 @@ namespace ts {
50035009
50045010 // A valid base type is `any`, any non-generic object type or intersection of non-generic
50055011 // object types.
5006- function isValidBaseType(type: Type): boolean {
5012+ function isValidBaseType(type: Type): type is BaseType {
50075013 return type.flags & (TypeFlags.Object | TypeFlags.NonPrimitive | TypeFlags.Any) && !isGenericMappedType(type) ||
50085014 type.flags & TypeFlags.Intersection && !forEach((<IntersectionType>type).types, t => !isValidBaseType(t));
50095015 }
@@ -5016,12 +5022,12 @@ namespace ts {
50165022 const baseType = getTypeFromTypeNode(node);
50175023 if (baseType !== unknownType) {
50185024 if (isValidBaseType(baseType)) {
5019- if (type !== baseType && !hasBaseType(<BaseType> baseType, type)) {
5025+ if (type !== baseType && !hasBaseType(baseType, type)) {
50205026 if (type.resolvedBaseTypes === emptyArray) {
50215027 type.resolvedBaseTypes = [<ObjectType>baseType];
50225028 }
50235029 else {
5024- type.resolvedBaseTypes.push(<ObjectType> baseType);
5030+ type.resolvedBaseTypes.push(baseType);
50255031 }
50265032 }
50275033 else {
@@ -5657,17 +5663,12 @@ namespace ts {
56575663 else {
56585664 // Combinations of function, class, enum and module
56595665 let members = emptySymbols;
5660- let constructSignatures: Signature[] = emptyArray;
56615666 let stringIndexInfo: IndexInfo = undefined;
56625667 if (symbol.exports) {
56635668 members = getExportsOfSymbol(symbol);
56645669 }
56655670 if (symbol.flags & SymbolFlags.Class) {
56665671 const classType = getDeclaredTypeOfClassOrInterface(symbol);
5667- constructSignatures = getSignaturesOfSymbol(symbol.members.get(InternalSymbolName.Constructor));
5668- if (!constructSignatures.length) {
5669- constructSignatures = getDefaultConstructSignatures(classType);
5670- }
56715672 const baseConstructorType = getBaseConstructorTypeOfClass(classType);
56725673 if (baseConstructorType.flags & (TypeFlags.Object | TypeFlags.Intersection | TypeFlags.TypeVariable)) {
56735674 members = createSymbolTable(getNamedMembers(members));
@@ -5678,14 +5679,23 @@ namespace ts {
56785679 }
56795680 }
56805681 const numberIndexInfo = symbol.flags & SymbolFlags.Enum ? enumNumberIndexInfo : undefined;
5681- setStructuredTypeMembers(type, members, emptyArray, constructSignatures , stringIndexInfo, numberIndexInfo);
5682+ setStructuredTypeMembers(type, members, emptyArray, emptyArray , stringIndexInfo, numberIndexInfo);
56825683 // We resolve the members before computing the signatures because a signature may use
56835684 // typeof with a qualified name expression that circularly references the type we are
56845685 // in the process of resolving (see issue #6072). The temporarily empty signature list
56855686 // will never be observed because a qualified name can't reference signatures.
56865687 if (symbol.flags & (SymbolFlags.Function | SymbolFlags.Method)) {
56875688 (<ResolvedType>type).callSignatures = getSignaturesOfSymbol(symbol);
56885689 }
5690+ // And likewise for construct signatures for classes
5691+ if (symbol.flags & SymbolFlags.Class) {
5692+ const classType = getDeclaredTypeOfClassOrInterface(symbol);
5693+ let constructSignatures = getSignaturesOfSymbol(symbol.members.get(InternalSymbolName.Constructor));
5694+ if (!constructSignatures.length) {
5695+ constructSignatures = getDefaultConstructSignatures(classType);
5696+ }
5697+ (<ResolvedType>type).constructSignatures = constructSignatures;
5698+ }
56895699 }
56905700 }
56915701
0 commit comments