Merged classes and interfaces must have identical type constraints

Previously, only interfaces needed to check this, but now that classes and
interfaces can merge, the check needs to happen in more places.
This commit is contained in:
Nathan Shively-Sanders
2016-02-19 11:36:35 -08:00
parent eacc092f87
commit bb2eb635d6
2 changed files with 23 additions and 9 deletions

View File

@@ -14013,7 +14013,7 @@ namespace ts {
}
}
// Check each type parameter and check that list has no duplicate type parameter declarations
/** Check each type parameter and check that type parameters have no duplicate type parameter declarations */
function checkTypeParameters(typeParameterDeclarations: TypeParameterDeclaration[]) {
if (typeParameterDeclarations) {
for (let i = 0, n = typeParameterDeclarations.length; i < n; i++) {
@@ -14031,6 +14031,23 @@ namespace ts {
}
}
/** Check that type parameter lists are identical across multiple declarations */
function checkTypeParameterListsIdentical(node: ClassLikeDeclaration | InterfaceDeclaration, symbol: Symbol) {
let firstDecl: ClassLikeDeclaration | InterfaceDeclaration;
if (symbol.declarations.length > 1) {
for (const declaration of symbol.declarations) {
if (declaration.kind === SyntaxKind.ClassDeclaration || declaration.kind === SyntaxKind.InterfaceDeclaration) {
if (!firstDecl) {
firstDecl = <ClassLikeDeclaration | InterfaceDeclaration>declaration;
}
else if (!areTypeParametersIdentical(firstDecl.typeParameters, node.typeParameters)) {
error(node.name, Diagnostics.All_declarations_must_have_identical_type_parameters);
}
}
}
}
}
function checkClassExpression(node: ClassExpression): Type {
checkClassLikeDeclaration(node);
checkNodeDeferred(node);
@@ -14064,6 +14081,7 @@ namespace ts {
const type = <InterfaceType>getDeclaredTypeOfSymbol(symbol);
const typeWithThis = getTypeWithThisArgument(type);
const staticType = <ObjectType>getTypeOfSymbol(symbol);
checkTypeParameterListsIdentical(node, symbol);
const baseTypeNode = getClassExtendsHeritageClauseElement(node);
if (baseTypeNode) {
@@ -14326,14 +14344,10 @@ namespace ts {
checkExportsOnMergedDeclarations(node);
const symbol = getSymbolOfNode(node);
const firstInterfaceDecl = <InterfaceDeclaration>getDeclarationOfKind(symbol, SyntaxKind.InterfaceDeclaration);
if (symbol.declarations.length > 1) {
if (node !== firstInterfaceDecl && !areTypeParametersIdentical(firstInterfaceDecl.typeParameters, node.typeParameters)) {
error(node.name, Diagnostics.All_declarations_of_an_interface_must_have_identical_type_parameters);
}
}
checkTypeParameterListsIdentical(node, symbol);
// Only check this symbol once
const firstInterfaceDecl = <InterfaceDeclaration>getDeclarationOfKind(symbol, SyntaxKind.InterfaceDeclaration);
if (node === firstInterfaceDecl) {
const type = <InterfaceType>getDeclaredTypeOfSymbol(symbol);
const typeWithThis = getTypeWithThisArgument(type);

View File

@@ -1311,7 +1311,7 @@
"category": "Error",
"code": 2427
},
"All declarations of an interface must have identical type parameters.": {
"All declarations must have identical type parameters.": {
"category": "Error",
"code": 2428
},
@@ -2801,4 +2801,4 @@
"category": "Error",
"code": 17009
}
}
}