From f30e73fc8028e482868c0ccbb7a9cf7b4a3983c6 Mon Sep 17 00:00:00 2001 From: Sheetal Nandi Date: Fri, 5 Oct 2018 15:37:41 -0700 Subject: [PATCH] Report the errors for static incompatibility only if instance types are assignable Fixes #26138 --- src/compiler/checker.ts | 7 ++-- ...taticMismatchBecauseOfPrototype.errors.txt | 19 ++++++++++ .../staticMismatchBecauseOfPrototype.js | 36 +++++++++++++++++++ .../staticMismatchBecauseOfPrototype.symbols | 26 ++++++++++++++ .../staticMismatchBecauseOfPrototype.types | 22 ++++++++++++ .../staticMismatchBecauseOfPrototype.ts | 11 ++++++ 6 files changed, 119 insertions(+), 2 deletions(-) create mode 100644 tests/baselines/reference/staticMismatchBecauseOfPrototype.errors.txt create mode 100644 tests/baselines/reference/staticMismatchBecauseOfPrototype.js create mode 100644 tests/baselines/reference/staticMismatchBecauseOfPrototype.symbols create mode 100644 tests/baselines/reference/staticMismatchBecauseOfPrototype.types create mode 100644 tests/cases/compiler/staticMismatchBecauseOfPrototype.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index ba0b180b71..2126b12894 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -26069,8 +26069,11 @@ namespace ts { if (!checkTypeAssignableTo(typeWithThis, baseWithThis, /*errorNode*/ undefined)) { issueMemberSpecificError(node, typeWithThis, baseWithThis, Diagnostics.Class_0_incorrectly_extends_base_class_1); } - checkTypeAssignableTo(staticType, getTypeWithoutSignatures(staticBaseType), node.name || node, - Diagnostics.Class_static_side_0_incorrectly_extends_base_class_static_side_1); + else { + // Report static side error only when instance type is assignable + checkTypeAssignableTo(staticType, getTypeWithoutSignatures(staticBaseType), node.name || node, + Diagnostics.Class_static_side_0_incorrectly_extends_base_class_static_side_1); + } if (baseConstructorType.flags & TypeFlags.TypeVariable && !isMixinConstructorType(staticType)) { error(node.name || node, Diagnostics.A_mixin_class_must_have_a_constructor_with_a_single_rest_parameter_of_type_any); } diff --git a/tests/baselines/reference/staticMismatchBecauseOfPrototype.errors.txt b/tests/baselines/reference/staticMismatchBecauseOfPrototype.errors.txt new file mode 100644 index 0000000000..4976019680 --- /dev/null +++ b/tests/baselines/reference/staticMismatchBecauseOfPrototype.errors.txt @@ -0,0 +1,19 @@ +tests/cases/compiler/staticMismatchBecauseOfPrototype.ts(10,5): error TS2416: Property 'n' in type 'B' is not assignable to the same property in base type 'A'. + Type 'string' is not assignable to type 'number'. + + +==== tests/cases/compiler/staticMismatchBecauseOfPrototype.ts (1 errors) ==== + interface A { + n: number; + } + declare var A: { + prototype: A; + new(): A; + }; + + class B extends A { + n = ""; + ~ +!!! error TS2416: Property 'n' in type 'B' is not assignable to the same property in base type 'A'. +!!! error TS2416: Type 'string' is not assignable to type 'number'. + } \ No newline at end of file diff --git a/tests/baselines/reference/staticMismatchBecauseOfPrototype.js b/tests/baselines/reference/staticMismatchBecauseOfPrototype.js new file mode 100644 index 0000000000..4bc7b24895 --- /dev/null +++ b/tests/baselines/reference/staticMismatchBecauseOfPrototype.js @@ -0,0 +1,36 @@ +//// [staticMismatchBecauseOfPrototype.ts] +interface A { + n: number; +} +declare var A: { + prototype: A; + new(): A; +}; + +class B extends A { + n = ""; +} + +//// [staticMismatchBecauseOfPrototype.js] +var __extends = (this && this.__extends) || (function () { + var extendStatics = function (d, b) { + extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return extendStatics(d, b); + }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +var B = /** @class */ (function (_super) { + __extends(B, _super); + function B() { + var _this = _super !== null && _super.apply(this, arguments) || this; + _this.n = ""; + return _this; + } + return B; +}(A)); diff --git a/tests/baselines/reference/staticMismatchBecauseOfPrototype.symbols b/tests/baselines/reference/staticMismatchBecauseOfPrototype.symbols new file mode 100644 index 0000000000..98abd4b9e1 --- /dev/null +++ b/tests/baselines/reference/staticMismatchBecauseOfPrototype.symbols @@ -0,0 +1,26 @@ +=== tests/cases/compiler/staticMismatchBecauseOfPrototype.ts === +interface A { +>A : Symbol(A, Decl(staticMismatchBecauseOfPrototype.ts, 0, 0), Decl(staticMismatchBecauseOfPrototype.ts, 3, 11)) + + n: number; +>n : Symbol(A.n, Decl(staticMismatchBecauseOfPrototype.ts, 0, 13)) +} +declare var A: { +>A : Symbol(A, Decl(staticMismatchBecauseOfPrototype.ts, 0, 0), Decl(staticMismatchBecauseOfPrototype.ts, 3, 11)) + + prototype: A; +>prototype : Symbol(prototype, Decl(staticMismatchBecauseOfPrototype.ts, 3, 16)) +>A : Symbol(A, Decl(staticMismatchBecauseOfPrototype.ts, 0, 0), Decl(staticMismatchBecauseOfPrototype.ts, 3, 11)) + + new(): A; +>A : Symbol(A, Decl(staticMismatchBecauseOfPrototype.ts, 0, 0), Decl(staticMismatchBecauseOfPrototype.ts, 3, 11)) + +}; + +class B extends A { +>B : Symbol(B, Decl(staticMismatchBecauseOfPrototype.ts, 6, 2)) +>A : Symbol(A, Decl(staticMismatchBecauseOfPrototype.ts, 0, 0), Decl(staticMismatchBecauseOfPrototype.ts, 3, 11)) + + n = ""; +>n : Symbol(B.n, Decl(staticMismatchBecauseOfPrototype.ts, 8, 19)) +} diff --git a/tests/baselines/reference/staticMismatchBecauseOfPrototype.types b/tests/baselines/reference/staticMismatchBecauseOfPrototype.types new file mode 100644 index 0000000000..d55c86b3fc --- /dev/null +++ b/tests/baselines/reference/staticMismatchBecauseOfPrototype.types @@ -0,0 +1,22 @@ +=== tests/cases/compiler/staticMismatchBecauseOfPrototype.ts === +interface A { + n: number; +>n : number +} +declare var A: { +>A : { new (): A; prototype: A; } + + prototype: A; +>prototype : A + + new(): A; +}; + +class B extends A { +>B : B +>A : A + + n = ""; +>n : string +>"" : "" +} diff --git a/tests/cases/compiler/staticMismatchBecauseOfPrototype.ts b/tests/cases/compiler/staticMismatchBecauseOfPrototype.ts new file mode 100644 index 0000000000..24d50f1951 --- /dev/null +++ b/tests/cases/compiler/staticMismatchBecauseOfPrototype.ts @@ -0,0 +1,11 @@ +interface A { + n: number; +} +declare var A: { + prototype: A; + new(): A; +}; + +class B extends A { + n = ""; +} \ No newline at end of file