From 303786a3b81de49cea4297b0dd9c8382cef0e526 Mon Sep 17 00:00:00 2001 From: Herrington Darkholme Date: Sun, 24 Dec 2017 17:05:05 +0800 Subject: [PATCH] fix #20018, allow skip constraint when merging interfaces --- src/compiler/checker.ts | 8 +-- ...erfacesWithDifferentConstraints.errors.txt | 31 ++++++++++- ...nericInterfacesWithDifferentConstraints.js | 23 ++++++++- ...InterfacesWithDifferentConstraints.symbols | 51 +++++++++++++++++++ ...icInterfacesWithDifferentConstraints.types | 51 +++++++++++++++++++ ...nericInterfacesWithDifferentConstraints.ts | 22 +++++++- 6 files changed, 179 insertions(+), 7 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 813e09f97ca26..f9c40d7463890 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -22633,9 +22633,11 @@ namespace ts { // 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))) { - return false; + if (sourceConstraint) { + // relax check if later interface augmentation has no constraint + if (!targetConstraint || !isTypeIdenticalTo(sourceConstraint, targetConstraint)) { + return false; + } } // If the type parameter node has a default and it is not identical to the default diff --git a/tests/baselines/reference/twoGenericInterfacesWithDifferentConstraints.errors.txt b/tests/baselines/reference/twoGenericInterfacesWithDifferentConstraints.errors.txt index 71d6f73d864ad..21a35e0553b4c 100644 --- a/tests/baselines/reference/twoGenericInterfacesWithDifferentConstraints.errors.txt +++ b/tests/baselines/reference/twoGenericInterfacesWithDifferentConstraints.errors.txt @@ -4,9 +4,11 @@ tests/cases/conformance/interfaces/declarationMerging/twoGenericInterfacesWithDi tests/cases/conformance/interfaces/declarationMerging/twoGenericInterfacesWithDifferentConstraints.ts(14,15): error TS2428: All declarations of 'B' must have identical type parameters. tests/cases/conformance/interfaces/declarationMerging/twoGenericInterfacesWithDifferentConstraints.ts(32,22): error TS2428: All declarations of 'A' must have identical type parameters. tests/cases/conformance/interfaces/declarationMerging/twoGenericInterfacesWithDifferentConstraints.ts(38,22): error TS2428: All declarations of 'A' must have identical type parameters. +tests/cases/conformance/interfaces/declarationMerging/twoGenericInterfacesWithDifferentConstraints.ts(53,11): error TS2428: All declarations of 'C' must have identical type parameters. +tests/cases/conformance/interfaces/declarationMerging/twoGenericInterfacesWithDifferentConstraints.ts(57,11): error TS2428: All declarations of 'C' must have identical type parameters. -==== tests/cases/conformance/interfaces/declarationMerging/twoGenericInterfacesWithDifferentConstraints.ts (6 errors) ==== +==== tests/cases/conformance/interfaces/declarationMerging/twoGenericInterfacesWithDifferentConstraints.ts (8 errors) ==== interface A { ~ !!! error TS2428: All declarations of 'A' must have identical type parameters. @@ -59,4 +61,29 @@ tests/cases/conformance/interfaces/declarationMerging/twoGenericInterfacesWithDi !!! error TS2428: All declarations of 'A' must have identical type parameters. y: T; } - } \ No newline at end of file + } + + interface B { + u: T; + v: Constraint; // ok + } + + interface B { // ok + x: T; + y: Constraint; // ok + } + + interface C { + ~ +!!! error TS2428: All declarations of 'C' must have identical type parameters. + x: T; + } + + interface C { // error + ~ +!!! error TS2428: All declarations of 'C' must have identical type parameters. + y: T; + } + + interface Constraint {} + \ No newline at end of file diff --git a/tests/baselines/reference/twoGenericInterfacesWithDifferentConstraints.js b/tests/baselines/reference/twoGenericInterfacesWithDifferentConstraints.js index 245da303d73e6..5b1964b2891ec 100644 --- a/tests/baselines/reference/twoGenericInterfacesWithDifferentConstraints.js +++ b/tests/baselines/reference/twoGenericInterfacesWithDifferentConstraints.js @@ -39,6 +39,27 @@ module M3 { export interface A { // error y: T; } -} +} + +interface B { + u: T; + v: Constraint; // ok +} + +interface B { // ok + x: T; + y: Constraint; // ok +} + +interface C { + x: T; +} + +interface C { // error + y: T; +} + +interface Constraint {} + //// [twoGenericInterfacesWithDifferentConstraints.js] diff --git a/tests/baselines/reference/twoGenericInterfacesWithDifferentConstraints.symbols b/tests/baselines/reference/twoGenericInterfacesWithDifferentConstraints.symbols index 46b0d397e09e4..6d802b9ff2c3c 100644 --- a/tests/baselines/reference/twoGenericInterfacesWithDifferentConstraints.symbols +++ b/tests/baselines/reference/twoGenericInterfacesWithDifferentConstraints.symbols @@ -99,3 +99,54 @@ module M3 { >T : Symbol(T, Decl(twoGenericInterfacesWithDifferentConstraints.ts, 31, 23), Decl(twoGenericInterfacesWithDifferentConstraints.ts, 37, 23)) } } + +interface B { +>B : Symbol(B, Decl(twoGenericInterfacesWithDifferentConstraints.ts, 40, 1), Decl(twoGenericInterfacesWithDifferentConstraints.ts, 45, 1)) +>T : Symbol(T, Decl(twoGenericInterfacesWithDifferentConstraints.ts, 42, 12), Decl(twoGenericInterfacesWithDifferentConstraints.ts, 47, 12)) + + u: T; +>u : Symbol(B.u, Decl(twoGenericInterfacesWithDifferentConstraints.ts, 42, 31)) +>T : Symbol(T, Decl(twoGenericInterfacesWithDifferentConstraints.ts, 42, 12), Decl(twoGenericInterfacesWithDifferentConstraints.ts, 47, 12)) + + v: Constraint; // ok +>v : Symbol(B.v, Decl(twoGenericInterfacesWithDifferentConstraints.ts, 43, 7)) +>Constraint : Symbol(Constraint, Decl(twoGenericInterfacesWithDifferentConstraints.ts, 58, 1)) +>T : Symbol(T, Decl(twoGenericInterfacesWithDifferentConstraints.ts, 42, 12), Decl(twoGenericInterfacesWithDifferentConstraints.ts, 47, 12)) +} + +interface B { // ok +>B : Symbol(B, Decl(twoGenericInterfacesWithDifferentConstraints.ts, 40, 1), Decl(twoGenericInterfacesWithDifferentConstraints.ts, 45, 1)) +>T : Symbol(T, Decl(twoGenericInterfacesWithDifferentConstraints.ts, 42, 12), Decl(twoGenericInterfacesWithDifferentConstraints.ts, 47, 12)) + + x: T; +>x : Symbol(B.x, Decl(twoGenericInterfacesWithDifferentConstraints.ts, 47, 16)) +>T : Symbol(T, Decl(twoGenericInterfacesWithDifferentConstraints.ts, 42, 12), Decl(twoGenericInterfacesWithDifferentConstraints.ts, 47, 12)) + + y: Constraint; // ok +>y : Symbol(B.y, Decl(twoGenericInterfacesWithDifferentConstraints.ts, 48, 7)) +>Constraint : Symbol(Constraint, Decl(twoGenericInterfacesWithDifferentConstraints.ts, 58, 1)) +>T : Symbol(T, Decl(twoGenericInterfacesWithDifferentConstraints.ts, 42, 12), Decl(twoGenericInterfacesWithDifferentConstraints.ts, 47, 12)) +} + +interface C { +>C : Symbol(C, Decl(twoGenericInterfacesWithDifferentConstraints.ts, 50, 1), Decl(twoGenericInterfacesWithDifferentConstraints.ts, 54, 1)) +>T : Symbol(T, Decl(twoGenericInterfacesWithDifferentConstraints.ts, 52, 12), Decl(twoGenericInterfacesWithDifferentConstraints.ts, 56, 12)) + + x: T; +>x : Symbol(C.x, Decl(twoGenericInterfacesWithDifferentConstraints.ts, 52, 16)) +>T : Symbol(T, Decl(twoGenericInterfacesWithDifferentConstraints.ts, 52, 12), Decl(twoGenericInterfacesWithDifferentConstraints.ts, 56, 12)) +} + +interface C { // error +>C : Symbol(C, Decl(twoGenericInterfacesWithDifferentConstraints.ts, 50, 1), Decl(twoGenericInterfacesWithDifferentConstraints.ts, 54, 1)) +>T : Symbol(T, Decl(twoGenericInterfacesWithDifferentConstraints.ts, 52, 12), Decl(twoGenericInterfacesWithDifferentConstraints.ts, 56, 12)) + + y: T; +>y : Symbol(C.y, Decl(twoGenericInterfacesWithDifferentConstraints.ts, 56, 31)) +>T : Symbol(T, Decl(twoGenericInterfacesWithDifferentConstraints.ts, 52, 12), Decl(twoGenericInterfacesWithDifferentConstraints.ts, 56, 12)) +} + +interface Constraint {} +>Constraint : Symbol(Constraint, Decl(twoGenericInterfacesWithDifferentConstraints.ts, 58, 1)) +>T : Symbol(T, Decl(twoGenericInterfacesWithDifferentConstraints.ts, 60, 21)) + diff --git a/tests/baselines/reference/twoGenericInterfacesWithDifferentConstraints.types b/tests/baselines/reference/twoGenericInterfacesWithDifferentConstraints.types index ca56778032b9b..8f7899549fc81 100644 --- a/tests/baselines/reference/twoGenericInterfacesWithDifferentConstraints.types +++ b/tests/baselines/reference/twoGenericInterfacesWithDifferentConstraints.types @@ -99,3 +99,54 @@ module M3 { >T : T } } + +interface B { +>B : B +>T : T + + u: T; +>u : T +>T : T + + v: Constraint; // ok +>v : Constraint +>Constraint : Constraint +>T : T +} + +interface B { // ok +>B : B +>T : T + + x: T; +>x : T +>T : T + + y: Constraint; // ok +>y : Constraint +>Constraint : Constraint +>T : T +} + +interface C { +>C : C +>T : T + + x: T; +>x : T +>T : T +} + +interface C { // error +>C : C +>T : T + + y: T; +>y : T +>T : T +} + +interface Constraint {} +>Constraint : Constraint +>T : T + diff --git a/tests/cases/conformance/interfaces/declarationMerging/twoGenericInterfacesWithDifferentConstraints.ts b/tests/cases/conformance/interfaces/declarationMerging/twoGenericInterfacesWithDifferentConstraints.ts index 181252c072142..4c698626eb003 100644 --- a/tests/cases/conformance/interfaces/declarationMerging/twoGenericInterfacesWithDifferentConstraints.ts +++ b/tests/cases/conformance/interfaces/declarationMerging/twoGenericInterfacesWithDifferentConstraints.ts @@ -38,4 +38,24 @@ module M3 { export interface A { // error y: T; } -} \ No newline at end of file +} + +interface B { + u: T; + v: Constraint; // ok +} + +interface B { // ok + x: T; + y: Constraint; // ok +} + +interface C { + x: T; +} + +interface C { // error + y: T; +} + +interface Constraint {}