diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 5da6244b552..74361a2403b 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -18403,16 +18403,110 @@ namespace ts { if (symbol.declarations.length === 1) { return; } - let firstDecl: ClassLikeDeclaration | InterfaceDeclaration; - for (const declaration of symbol.declarations) { - if (declaration.kind === SyntaxKind.ClassDeclaration || declaration.kind === SyntaxKind.InterfaceDeclaration) { - if (!firstDecl) { - firstDecl = declaration; - } - else if (!areTypeParametersIdentical(firstDecl.typeParameters, node.typeParameters)) { - error(node.name, Diagnostics.All_declarations_of_0_must_have_identical_type_parameters, node.name.text); + + // Resolve the type parameters and minimum type argument count for all declarations + resolveTypeParametersOfClassOrInterface(symbol); + + const { typeParameters, minTypeArgumentCount } = getSymbolLinks(symbol); + const maxTypeArgumentCount = typeParameters ? typeParameters.length : 0; + const numTypeParameters = node.typeParameters ? node.typeParameters.length : 0; + + // If this declaration has too few or too many type parameters, we report an error + if (numTypeParameters < minTypeArgumentCount || numTypeParameters > maxTypeArgumentCount) { + error(node.name, Diagnostics.All_declarations_of_0_must_have_identical_type_parameters, node.name.text); + return; + } + + for (let i = 0; i < numTypeParameters; i++) { + const source = node.typeParameters[i]; + const target = typeParameters[i]; + + // If the type parameter node does not have the same name as the resolved type + // parameter at this position, we report an error. + if (source.name.text !== target.symbol.name) { + error(node.name, Diagnostics.All_declarations_of_0_must_have_identical_type_parameters, node.name.text); + return; + } + + // 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); + if ((sourceConstraint || targetConstraint) && + (!sourceConstraint || !targetConstraint || !isTypeIdenticalTo(sourceConstraint, targetConstraint))) { + error(node.name, Diagnostics.All_declarations_of_0_must_have_identical_type_parameters, node.name.text); + return; + } + + // If the type parameter node has a default and it is not identical to the default + // for the type parameter at this position, we report an error. + const sourceDefault = source.default && getTypeFromTypeNode(source.default); + const targetDefault = getDefaultFromTypeParameter(target); + if (sourceDefault && targetDefault && !isTypeIdenticalTo(sourceDefault, targetDefault)) { + error(node.name, Diagnostics.All_declarations_of_0_must_have_identical_type_parameters, node.name.text); + return; + } + } + } + + function resolveTypeParametersOfClassOrInterface(symbol: Symbol) { + const links = getSymbolLinks(symbol); + if (!links.typeParameters) { + let typeParameters: TypeParameter[] | undefined; + let minTypeArgumentCount = -1; + let maxTypeArgumentCount = -1; + for (const declaration of symbol.declarations) { + if (declaration.kind === SyntaxKind.ClassDeclaration || declaration.kind === SyntaxKind.InterfaceDeclaration) { + const typeParameterNodes = (declaration).typeParameters; + const numTypeParameters = typeParameterNodes ? typeParameterNodes.length : 0; + if (maxTypeArgumentCount === -1) { + // For the first declaration, establish the initial maximum and + // minimum type argument counts. These only change when we + // encounter default type arguments. + maxTypeArgumentCount = numTypeParameters; + minTypeArgumentCount = numTypeParameters; + } + + if (typeParameterNodes) { + if (!typeParameters) { + typeParameters = []; + } + + for (let i = 0; i < typeParameterNodes.length; i++) { + if (typeParameterNodes[i].default) { + // When we encounter a type parameter with a default, establish + // new minimum and maximum type arguments if necessary. + if (minTypeArgumentCount > i) { + minTypeArgumentCount = i; + } + if (maxTypeArgumentCount < i + 1) { + maxTypeArgumentCount = i + 1; + } + } + if (typeParameters.length <= i) { + // When we encounter a new type parameter at this position, + // get the declared type for the type parameter. If another + // declaration attempts to establish a type parameter with a + // different name or constraint than the first one we find, + // we will report an error when checking the type parameters. + typeParameters[i] = getDeclaredTypeOfTypeParameter(getSymbolOfNode(typeParameterNodes[i])); + } + } + } } } + if (maxTypeArgumentCount === -1) { + maxTypeArgumentCount = 0; + } + if (minTypeArgumentCount === -1) { + minTypeArgumentCount = maxTypeArgumentCount; + } + if (typeParameters && typeParameters.length > maxTypeArgumentCount) { + // Trim the type parameters to the maximum length + typeParameters.length = maxTypeArgumentCount; + } + links.typeParameters = typeParameters || emptyArray; + links.minTypeArgumentCount = minTypeArgumentCount; } } @@ -18654,36 +18748,6 @@ namespace ts { return kind === SyntaxKind.GetAccessor || kind === SyntaxKind.SetAccessor; } - function areTypeParametersIdentical(list1: TypeParameterDeclaration[], list2: TypeParameterDeclaration[]) { - if (!list1 && !list2) { - return true; - } - if (!list1 || !list2 || list1.length !== list2.length) { - return false; - } - // TypeScript 1.0 spec (April 2014): - // When a generic interface has multiple declarations, all declarations must have identical type parameter - // lists, i.e. identical type parameter names with identical constraints in identical order. - for (let i = 0; i < list1.length; i++) { - const tp1 = list1[i]; - const tp2 = list2[i]; - if (tp1.name.text !== tp2.name.text) { - return false; - } - if (tp1.constraint || tp2.constraint) { - if (!tp1.constraint || !tp2.constraint || !isTypeIdenticalTo(getTypeFromTypeNode(tp1.constraint), getTypeFromTypeNode(tp2.constraint))) { - return false; - } - } - if (tp1.default || tp2.default) { - if (!tp1.default || !tp2.default || !isTypeIdenticalTo(getTypeFromTypeNode(tp1.default), getTypeFromTypeNode(tp2.default))) { - return false; - } - } - } - return true; - } - function checkInheritedPropertiesAreIdentical(type: InterfaceType, typeNode: Node): boolean { const baseTypes = getBaseTypes(type); if (baseTypes.length < 2) { diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 192ef888b11..ae6e1d351d8 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -24,6 +24,20 @@ namespace ts { return undefined; } + export function findDeclaration(symbol: Symbol, predicate: (node: Declaration) => node is T): T | undefined; + export function findDeclaration(symbol: Symbol, predicate: (node: Declaration) => boolean): Declaration | undefined; + export function findDeclaration(symbol: Symbol, predicate: (node: Declaration) => boolean): Declaration | undefined { + const declarations = symbol.declarations; + if (declarations) { + for (const declaration of declarations) { + if (predicate(declaration)) { + return declaration; + } + } + } + return undefined; + } + export interface StringSymbolWriter extends SymbolWriter { string(): string; } diff --git a/tests/baselines/reference/genericDefaults.js b/tests/baselines/reference/genericDefaults.js index c61a42c9651..a2271681e13 100644 --- a/tests/baselines/reference/genericDefaults.js +++ b/tests/baselines/reference/genericDefaults.js @@ -86,6 +86,11 @@ const i03c02 = (>x).a; const i03c03 = (>x).a; const i03c04 = (>x).a; +interface i04 {} +interface i04 {} +interface i04 {} +interface i04 {} + interface Base01 { a: T; } interface Base01Constructor { new (a?: T): Base01; } @@ -293,6 +298,14 @@ declare const i03c01: [1, 1]; declare const i03c02: [number, number]; declare const i03c03: [1, 1]; declare const i03c04: [number, 1]; +interface i04 { +} +interface i04 { +} +interface i04 { +} +interface i04 { +} interface Base01 { a: T; } diff --git a/tests/baselines/reference/genericDefaults.symbols b/tests/baselines/reference/genericDefaults.symbols index a43b6fa9f43..67b61a0a252 100644 --- a/tests/baselines/reference/genericDefaults.symbols +++ b/tests/baselines/reference/genericDefaults.symbols @@ -408,81 +408,97 @@ const i03c04 = (>x).a; >x : Symbol(x, Decl(genericDefaults.ts, 0, 13)) >a : Symbol(i03.a, Decl(genericDefaults.ts, 80, 50)) +interface i04 {} +>i04 : Symbol(i04, Decl(genericDefaults.ts, 85, 37), Decl(genericDefaults.ts, 87, 16), Decl(genericDefaults.ts, 88, 19), Decl(genericDefaults.ts, 89, 28)) + +interface i04 {} +>i04 : Symbol(i04, Decl(genericDefaults.ts, 85, 37), Decl(genericDefaults.ts, 87, 16), Decl(genericDefaults.ts, 88, 19), Decl(genericDefaults.ts, 89, 28)) +>T : Symbol(T, Decl(genericDefaults.ts, 88, 14), Decl(genericDefaults.ts, 89, 14), Decl(genericDefaults.ts, 90, 14)) + +interface i04 {} +>i04 : Symbol(i04, Decl(genericDefaults.ts, 85, 37), Decl(genericDefaults.ts, 87, 16), Decl(genericDefaults.ts, 88, 19), Decl(genericDefaults.ts, 89, 28)) +>T : Symbol(T, Decl(genericDefaults.ts, 88, 14), Decl(genericDefaults.ts, 89, 14), Decl(genericDefaults.ts, 90, 14)) + +interface i04 {} +>i04 : Symbol(i04, Decl(genericDefaults.ts, 85, 37), Decl(genericDefaults.ts, 87, 16), Decl(genericDefaults.ts, 88, 19), Decl(genericDefaults.ts, 89, 28)) +>T : Symbol(T, Decl(genericDefaults.ts, 88, 14), Decl(genericDefaults.ts, 89, 14), Decl(genericDefaults.ts, 90, 14)) +>U : Symbol(U, Decl(genericDefaults.ts, 90, 25)) + interface Base01 { a: T; } ->Base01 : Symbol(Base01, Decl(genericDefaults.ts, 85, 37), Decl(genericDefaults.ts, 90, 13)) ->T : Symbol(T, Decl(genericDefaults.ts, 87, 17)) ->a : Symbol(Base01.a, Decl(genericDefaults.ts, 87, 21)) ->T : Symbol(T, Decl(genericDefaults.ts, 87, 17)) +>Base01 : Symbol(Base01, Decl(genericDefaults.ts, 90, 40), Decl(genericDefaults.ts, 95, 13)) +>T : Symbol(T, Decl(genericDefaults.ts, 92, 17)) +>a : Symbol(Base01.a, Decl(genericDefaults.ts, 92, 21)) +>T : Symbol(T, Decl(genericDefaults.ts, 92, 17)) interface Base01Constructor { new (a?: T): Base01; } ->Base01Constructor : Symbol(Base01Constructor, Decl(genericDefaults.ts, 87, 29)) ->T : Symbol(T, Decl(genericDefaults.ts, 88, 35)) ->a : Symbol(a, Decl(genericDefaults.ts, 88, 47)) ->T : Symbol(T, Decl(genericDefaults.ts, 88, 35)) ->Base01 : Symbol(Base01, Decl(genericDefaults.ts, 85, 37), Decl(genericDefaults.ts, 90, 13)) ->T : Symbol(T, Decl(genericDefaults.ts, 88, 35)) +>Base01Constructor : Symbol(Base01Constructor, Decl(genericDefaults.ts, 92, 29)) +>T : Symbol(T, Decl(genericDefaults.ts, 93, 35)) +>a : Symbol(a, Decl(genericDefaults.ts, 93, 47)) +>T : Symbol(T, Decl(genericDefaults.ts, 93, 35)) +>Base01 : Symbol(Base01, Decl(genericDefaults.ts, 90, 40), Decl(genericDefaults.ts, 95, 13)) +>T : Symbol(T, Decl(genericDefaults.ts, 93, 35)) declare const Base01: Base01Constructor; ->Base01 : Symbol(Base01, Decl(genericDefaults.ts, 85, 37), Decl(genericDefaults.ts, 90, 13)) ->Base01Constructor : Symbol(Base01Constructor, Decl(genericDefaults.ts, 87, 29)) +>Base01 : Symbol(Base01, Decl(genericDefaults.ts, 90, 40), Decl(genericDefaults.ts, 95, 13)) +>Base01Constructor : Symbol(Base01Constructor, Decl(genericDefaults.ts, 92, 29)) const Base01c00 = new Base01(); ->Base01c00 : Symbol(Base01c00, Decl(genericDefaults.ts, 91, 5)) ->Base01 : Symbol(Base01, Decl(genericDefaults.ts, 85, 37), Decl(genericDefaults.ts, 90, 13)) +>Base01c00 : Symbol(Base01c00, Decl(genericDefaults.ts, 96, 5)) +>Base01 : Symbol(Base01, Decl(genericDefaults.ts, 90, 40), Decl(genericDefaults.ts, 95, 13)) const Base01c01 = new Base01(1); ->Base01c01 : Symbol(Base01c01, Decl(genericDefaults.ts, 92, 5)) ->Base01 : Symbol(Base01, Decl(genericDefaults.ts, 85, 37), Decl(genericDefaults.ts, 90, 13)) +>Base01c01 : Symbol(Base01c01, Decl(genericDefaults.ts, 97, 5)) +>Base01 : Symbol(Base01, Decl(genericDefaults.ts, 90, 40), Decl(genericDefaults.ts, 95, 13)) const Base01c02 = new Base01(); ->Base01c02 : Symbol(Base01c02, Decl(genericDefaults.ts, 93, 5)) ->Base01 : Symbol(Base01, Decl(genericDefaults.ts, 85, 37), Decl(genericDefaults.ts, 90, 13)) +>Base01c02 : Symbol(Base01c02, Decl(genericDefaults.ts, 98, 5)) +>Base01 : Symbol(Base01, Decl(genericDefaults.ts, 90, 40), Decl(genericDefaults.ts, 95, 13)) const Base01c03 = new Base01(1); ->Base01c03 : Symbol(Base01c03, Decl(genericDefaults.ts, 94, 5)) ->Base01 : Symbol(Base01, Decl(genericDefaults.ts, 85, 37), Decl(genericDefaults.ts, 90, 13)) +>Base01c03 : Symbol(Base01c03, Decl(genericDefaults.ts, 99, 5)) +>Base01 : Symbol(Base01, Decl(genericDefaults.ts, 90, 40), Decl(genericDefaults.ts, 95, 13)) declare class Derived01 extends Base01 { } ->Derived01 : Symbol(Derived01, Decl(genericDefaults.ts, 94, 40)) ->T : Symbol(T, Decl(genericDefaults.ts, 96, 24)) ->Base01 : Symbol(Base01, Decl(genericDefaults.ts, 85, 37), Decl(genericDefaults.ts, 90, 13)) ->T : Symbol(T, Decl(genericDefaults.ts, 96, 24)) +>Derived01 : Symbol(Derived01, Decl(genericDefaults.ts, 99, 40)) +>T : Symbol(T, Decl(genericDefaults.ts, 101, 24)) +>Base01 : Symbol(Base01, Decl(genericDefaults.ts, 90, 40), Decl(genericDefaults.ts, 95, 13)) +>T : Symbol(T, Decl(genericDefaults.ts, 101, 24)) const Derived01c00 = new Derived01(); ->Derived01c00 : Symbol(Derived01c00, Decl(genericDefaults.ts, 97, 5)) ->Derived01 : Symbol(Derived01, Decl(genericDefaults.ts, 94, 40)) +>Derived01c00 : Symbol(Derived01c00, Decl(genericDefaults.ts, 102, 5)) +>Derived01 : Symbol(Derived01, Decl(genericDefaults.ts, 99, 40)) const Derived01c01 = new Derived01(1); ->Derived01c01 : Symbol(Derived01c01, Decl(genericDefaults.ts, 98, 5)) ->Derived01 : Symbol(Derived01, Decl(genericDefaults.ts, 94, 40)) +>Derived01c01 : Symbol(Derived01c01, Decl(genericDefaults.ts, 103, 5)) +>Derived01 : Symbol(Derived01, Decl(genericDefaults.ts, 99, 40)) const Derived01c02 = new Derived01(); ->Derived01c02 : Symbol(Derived01c02, Decl(genericDefaults.ts, 99, 5)) ->Derived01 : Symbol(Derived01, Decl(genericDefaults.ts, 94, 40)) +>Derived01c02 : Symbol(Derived01c02, Decl(genericDefaults.ts, 104, 5)) +>Derived01 : Symbol(Derived01, Decl(genericDefaults.ts, 99, 40)) const Derived01c03 = new Derived01(1); ->Derived01c03 : Symbol(Derived01c03, Decl(genericDefaults.ts, 100, 5)) ->Derived01 : Symbol(Derived01, Decl(genericDefaults.ts, 94, 40)) +>Derived01c03 : Symbol(Derived01c03, Decl(genericDefaults.ts, 105, 5)) +>Derived01 : Symbol(Derived01, Decl(genericDefaults.ts, 99, 40)) declare class Derived02 extends Base01 { } ->Derived02 : Symbol(Derived02, Decl(genericDefaults.ts, 100, 46)) ->T : Symbol(T, Decl(genericDefaults.ts, 102, 24)) ->Base01 : Symbol(Base01, Decl(genericDefaults.ts, 85, 37), Decl(genericDefaults.ts, 90, 13)) ->T : Symbol(T, Decl(genericDefaults.ts, 102, 24)) +>Derived02 : Symbol(Derived02, Decl(genericDefaults.ts, 105, 46)) +>T : Symbol(T, Decl(genericDefaults.ts, 107, 24)) +>Base01 : Symbol(Base01, Decl(genericDefaults.ts, 90, 40), Decl(genericDefaults.ts, 95, 13)) +>T : Symbol(T, Decl(genericDefaults.ts, 107, 24)) const Derived02c00 = new Derived02(); ->Derived02c00 : Symbol(Derived02c00, Decl(genericDefaults.ts, 103, 5)) ->Derived02 : Symbol(Derived02, Decl(genericDefaults.ts, 100, 46)) +>Derived02c00 : Symbol(Derived02c00, Decl(genericDefaults.ts, 108, 5)) +>Derived02 : Symbol(Derived02, Decl(genericDefaults.ts, 105, 46)) const Derived02c01 = new Derived02(1); ->Derived02c01 : Symbol(Derived02c01, Decl(genericDefaults.ts, 104, 5)) ->Derived02 : Symbol(Derived02, Decl(genericDefaults.ts, 100, 46)) +>Derived02c01 : Symbol(Derived02c01, Decl(genericDefaults.ts, 109, 5)) +>Derived02 : Symbol(Derived02, Decl(genericDefaults.ts, 105, 46)) const Derived02c02 = new Derived02(); ->Derived02c02 : Symbol(Derived02c02, Decl(genericDefaults.ts, 105, 5)) ->Derived02 : Symbol(Derived02, Decl(genericDefaults.ts, 100, 46)) +>Derived02c02 : Symbol(Derived02c02, Decl(genericDefaults.ts, 110, 5)) +>Derived02 : Symbol(Derived02, Decl(genericDefaults.ts, 105, 46)) const Derived02c03 = new Derived02(1); ->Derived02c03 : Symbol(Derived02c03, Decl(genericDefaults.ts, 106, 5)) ->Derived02 : Symbol(Derived02, Decl(genericDefaults.ts, 100, 46)) +>Derived02c03 : Symbol(Derived02c03, Decl(genericDefaults.ts, 111, 5)) +>Derived02 : Symbol(Derived02, Decl(genericDefaults.ts, 105, 46)) diff --git a/tests/baselines/reference/genericDefaults.types b/tests/baselines/reference/genericDefaults.types index 7f50e03744c..70f67497f21 100644 --- a/tests/baselines/reference/genericDefaults.types +++ b/tests/baselines/reference/genericDefaults.types @@ -536,6 +536,22 @@ const i03c04 = (>x).a; >x : any >a : [number, 1] +interface i04 {} +>i04 : i04 + +interface i04 {} +>i04 : i04 +>T : T + +interface i04 {} +>i04 : i04 +>T : T + +interface i04 {} +>i04 : i04 +>T : T +>U : U + interface Base01 { a: T; } >Base01 : Base01 >T : T diff --git a/tests/baselines/reference/genericDefaultsErrors.errors.txt b/tests/baselines/reference/genericDefaultsErrors.errors.txt index aaf1f0b6cf0..a75a1744879 100644 --- a/tests/baselines/reference/genericDefaultsErrors.errors.txt +++ b/tests/baselines/reference/genericDefaultsErrors.errors.txt @@ -93,38 +93,38 @@ tests/cases/compiler/genericDefaultsErrors.ts(42,15): error TS2707: Generic type ~~~~~~~~~~~~~~~~~ !!! error TS2346: Supplied parameters do not match any signature of call target. - interface i00 { } - interface i00 { } + interface i00 { } // ok + interface i00 { } // error ~~~ !!! error TS2428: All declarations of 'i00' must have identical type parameters. - interface i01 { } - interface i01 { } + interface i01 { } // ok + interface i01 { } // error ~~~ !!! error TS2428: All declarations of 'i01' must have identical type parameters. - interface i02 { } + interface i02 { } // error ~ !!! error TS2706: Type parameter 'T' has a circular default. - interface i03 { } + interface i03 { } // error ~ !!! error TS2706: Type parameter 'T' has a circular default. ~ !!! error TS2706: Type parameter 'U' has a circular default. - interface i04 { } + interface i04 { } // error ~ !!! error TS2705: Required type parameters may not follow optional type parameters - interface i05 { } + interface i05 { } // error ~~~~~~ !!! error TS2344: Type 'number' does not satisfy the constraint 'string'. - interface i06 { } + interface i06 { } // error ~ !!! error TS2344: Type 'T' does not satisfy the constraint 'number'. !!! error TS2344: Type 'string' is not assignable to type 'number'. - interface i07 { } + interface i07 { } // error ~ !!! error TS2344: Type 'T' does not satisfy the constraint 'number'. - interface i08 { } + interface i08 { } // error ~~~~~~ !!! error TS2344: Type 'number' does not satisfy the constraint 'T'. diff --git a/tests/baselines/reference/genericDefaultsErrors.js b/tests/baselines/reference/genericDefaultsErrors.js index 6a624fae4d4..dc0670d5272 100644 --- a/tests/baselines/reference/genericDefaultsErrors.js +++ b/tests/baselines/reference/genericDefaultsErrors.js @@ -21,19 +21,19 @@ f11<1, 2>(); // ok f11<1, 2, 3>(); // ok f11<1, 2, 3, 4>(); // error -interface i00 { } -interface i00 { } +interface i00 { } // ok +interface i00 { } // error -interface i01 { } -interface i01 { } +interface i01 { } // ok +interface i01 { } // error -interface i02 { } -interface i03 { } -interface i04 { } -interface i05 { } -interface i06 { } -interface i07 { } -interface i08 { } +interface i02 { } // error +interface i03 { } // error +interface i04 { } // error +interface i05 { } // error +interface i06 { } // error +interface i07 { } // error +interface i08 { } // error interface i09 { } type i09t00 = i09; // error @@ -74,7 +74,7 @@ declare function f10(): void; interface i00 { } -interface i00 { +interface i00 { } interface i01 { } diff --git a/tests/cases/compiler/genericDefaults.ts b/tests/cases/compiler/genericDefaults.ts index abba8f2d8d6..10dbcf1025e 100644 --- a/tests/cases/compiler/genericDefaults.ts +++ b/tests/cases/compiler/genericDefaults.ts @@ -86,6 +86,11 @@ const i03c02 = (>x).a; const i03c03 = (>x).a; const i03c04 = (>x).a; +interface i04 {} +interface i04 {} +interface i04 {} +interface i04 {} + interface Base01 { a: T; } interface Base01Constructor { new (a?: T): Base01; } diff --git a/tests/cases/compiler/genericDefaultsErrors.ts b/tests/cases/compiler/genericDefaultsErrors.ts index e7fb7be81ae..985300f6607 100644 --- a/tests/cases/compiler/genericDefaultsErrors.ts +++ b/tests/cases/compiler/genericDefaultsErrors.ts @@ -21,19 +21,19 @@ f11<1, 2>(); // ok f11<1, 2, 3>(); // ok f11<1, 2, 3, 4>(); // error -interface i00 { } -interface i00 { } +interface i00 { } // ok +interface i00 { } // error -interface i01 { } -interface i01 { } +interface i01 { } // ok +interface i01 { } // error -interface i02 { } -interface i03 { } -interface i04 { } -interface i05 { } -interface i06 { } -interface i07 { } -interface i08 { } +interface i02 { } // error +interface i03 { } // error +interface i04 { } // error +interface i05 { } // error +interface i06 { } // error +interface i07 { } // error +interface i08 { } // error interface i09 { } type i09t00 = i09; // error