mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-02-04 21:53:42 -06:00
Merge pull request #3722 from Microsoft/abstractConstructorAssignability
Abstract constructor assignability
This commit is contained in:
commit
7664f3410c
@ -4903,9 +4903,38 @@ namespace ts {
|
||||
let targetSignatures = getSignaturesOfType(target, kind);
|
||||
let result = Ternary.True;
|
||||
let saveErrorInfo = errorInfo;
|
||||
|
||||
// Because the "abstractness" of a class is the same across all construct signatures
|
||||
// (internally we are checking the corresponding declaration), it is enough to perform
|
||||
// the check and report an error once over all pairs of source and target construct signatures.
|
||||
let sourceSig = sourceSignatures[0];
|
||||
// Note that in an extends-clause, targetSignatures is stripped, so the check never proceeds.
|
||||
let targetSig = targetSignatures[0];
|
||||
|
||||
if (sourceSig && targetSig) {
|
||||
let sourceErasedSignature = getErasedSignature(sourceSig);
|
||||
let targetErasedSignature = getErasedSignature(targetSig);
|
||||
|
||||
let sourceReturnType = sourceErasedSignature && getReturnTypeOfSignature(sourceErasedSignature);
|
||||
let targetReturnType = targetErasedSignature && getReturnTypeOfSignature(targetErasedSignature);
|
||||
|
||||
let sourceReturnDecl = sourceReturnType && sourceReturnType.symbol && getDeclarationOfKind(sourceReturnType.symbol, SyntaxKind.ClassDeclaration);
|
||||
let targetReturnDecl = targetReturnType && targetReturnType.symbol && getDeclarationOfKind(targetReturnType.symbol, SyntaxKind.ClassDeclaration);
|
||||
let sourceIsAbstract = sourceReturnDecl && sourceReturnDecl.flags & NodeFlags.Abstract;
|
||||
let targetIsAbstract = targetReturnDecl && targetReturnDecl.flags & NodeFlags.Abstract;
|
||||
|
||||
if (sourceIsAbstract && !targetIsAbstract) {
|
||||
if (reportErrors) {
|
||||
reportError(Diagnostics.Cannot_assign_an_abstract_constructor_type_to_a_non_abstract_constructor_type);
|
||||
}
|
||||
return Ternary.False;
|
||||
}
|
||||
}
|
||||
|
||||
outer: for (let t of targetSignatures) {
|
||||
if (!t.hasStringLiterals || target.flags & TypeFlags.FromSignature) {
|
||||
let localErrors = reportErrors;
|
||||
let checkedAbstractAssignability = false;
|
||||
for (let s of sourceSignatures) {
|
||||
if (!s.hasStringLiterals || source.flags & TypeFlags.FromSignature) {
|
||||
let related = signatureRelatedTo(s, t, localErrors);
|
||||
@ -5012,10 +5041,11 @@ namespace ts {
|
||||
return Ternary.False;
|
||||
}
|
||||
|
||||
let t = getReturnTypeOfSignature(target);
|
||||
if (t === voidType) return result;
|
||||
let s = getReturnTypeOfSignature(source);
|
||||
return result & isRelatedTo(s, t, reportErrors);
|
||||
let targetReturnType = getReturnTypeOfSignature(target);
|
||||
if (targetReturnType === voidType) return result;
|
||||
let sourceReturnType = getReturnTypeOfSignature(source);
|
||||
|
||||
return result & isRelatedTo(sourceReturnType, targetReturnType, reportErrors);
|
||||
}
|
||||
|
||||
function signaturesIdenticalTo(source: Type, target: Type, kind: SignatureKind): Ternary {
|
||||
|
||||
@ -407,7 +407,7 @@ namespace ts {
|
||||
Classes_containing_abstract_methods_must_be_marked_abstract: { code: 2514, category: DiagnosticCategory.Error, key: "Classes containing abstract methods must be marked abstract." },
|
||||
Non_abstract_class_0_does_not_implement_inherited_abstract_member_1_from_class_2: { code: 2515, category: DiagnosticCategory.Error, key: "Non-abstract class '{0}' does not implement inherited abstract member '{1}' from class '{2}'." },
|
||||
All_declarations_of_an_abstract_method_must_be_consecutive: { code: 2516, category: DiagnosticCategory.Error, key: "All declarations of an abstract method must be consecutive." },
|
||||
Constructor_objects_of_abstract_type_cannot_be_assigned_to_constructor_objects_of_non_abstract_type: { code: 2517, category: DiagnosticCategory.Error, key: "Constructor objects of abstract type cannot be assigned to constructor objects of non-abstract type" },
|
||||
Cannot_assign_an_abstract_constructor_type_to_a_non_abstract_constructor_type: { code: 2517, category: DiagnosticCategory.Error, key: "Cannot assign an abstract constructor type to a non-abstract constructor type." },
|
||||
Only_an_ambient_class_can_be_merged_with_an_interface: { code: 2518, category: DiagnosticCategory.Error, key: "Only an ambient class can be merged with an interface." },
|
||||
Duplicate_identifier_0_Compiler_uses_declaration_1_to_support_async_functions: { code: 2520, category: DiagnosticCategory.Error, key: "Duplicate identifier '{0}'. Compiler uses declaration '{1}' to support async functions." },
|
||||
Expression_resolves_to_variable_declaration_0_that_compiler_uses_to_support_async_functions: { code: 2521, category: DiagnosticCategory.Error, key: "Expression resolves to variable declaration '{0}' that compiler uses to support async functions." },
|
||||
|
||||
@ -1617,7 +1617,7 @@
|
||||
"category": "Error",
|
||||
"code": 2516
|
||||
},
|
||||
"Constructor objects of abstract type cannot be assigned to constructor objects of non-abstract type": {
|
||||
"Cannot assign an abstract constructor type to a non-abstract constructor type.": {
|
||||
"category": "Error",
|
||||
"code":2517
|
||||
},
|
||||
|
||||
@ -0,0 +1,31 @@
|
||||
tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractClinterfaceAssignability.ts(23,1): error TS2322: Type 'typeof A' is not assignable to type 'IConstructor'.
|
||||
Cannot assign an abstract constructor type to a non-abstract constructor type.
|
||||
|
||||
|
||||
==== tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractClinterfaceAssignability.ts (1 errors) ====
|
||||
interface I {
|
||||
x: number;
|
||||
}
|
||||
|
||||
interface IConstructor {
|
||||
new (): I;
|
||||
|
||||
y: number;
|
||||
prototype: I;
|
||||
}
|
||||
|
||||
var I: IConstructor;
|
||||
|
||||
abstract class A {
|
||||
x: number;
|
||||
static y: number;
|
||||
}
|
||||
|
||||
var AA: typeof A;
|
||||
AA = I;
|
||||
|
||||
var AAA: typeof I;
|
||||
AAA = A;
|
||||
~~~
|
||||
!!! error TS2322: Type 'typeof A' is not assignable to type 'IConstructor'.
|
||||
!!! error TS2322: Cannot assign an abstract constructor type to a non-abstract constructor type.
|
||||
@ -0,0 +1,36 @@
|
||||
//// [classAbstractClinterfaceAssignability.ts]
|
||||
interface I {
|
||||
x: number;
|
||||
}
|
||||
|
||||
interface IConstructor {
|
||||
new (): I;
|
||||
|
||||
y: number;
|
||||
prototype: I;
|
||||
}
|
||||
|
||||
var I: IConstructor;
|
||||
|
||||
abstract class A {
|
||||
x: number;
|
||||
static y: number;
|
||||
}
|
||||
|
||||
var AA: typeof A;
|
||||
AA = I;
|
||||
|
||||
var AAA: typeof I;
|
||||
AAA = A;
|
||||
|
||||
//// [classAbstractClinterfaceAssignability.js]
|
||||
var I;
|
||||
var A = (function () {
|
||||
function A() {
|
||||
}
|
||||
return A;
|
||||
})();
|
||||
var AA;
|
||||
AA = I;
|
||||
var AAA;
|
||||
AAA = A;
|
||||
@ -0,0 +1,30 @@
|
||||
tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractConstructorAssignability.ts(8,5): error TS2322: Type 'typeof B' is not assignable to type 'typeof A'.
|
||||
Cannot assign an abstract constructor type to a non-abstract constructor type.
|
||||
tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractConstructorAssignability.ts(10,5): error TS2322: Type 'typeof B' is not assignable to type 'typeof C'.
|
||||
Cannot assign an abstract constructor type to a non-abstract constructor type.
|
||||
tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractConstructorAssignability.ts(13,1): error TS2511: Cannot create an instance of the abstract class 'B'.
|
||||
|
||||
|
||||
==== tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractConstructorAssignability.ts (3 errors) ====
|
||||
|
||||
class A {}
|
||||
|
||||
abstract class B extends A {}
|
||||
|
||||
class C extends B {}
|
||||
|
||||
var AA : typeof A = B;
|
||||
~~
|
||||
!!! error TS2322: Type 'typeof B' is not assignable to type 'typeof A'.
|
||||
!!! error TS2322: Cannot assign an abstract constructor type to a non-abstract constructor type.
|
||||
var BB : typeof B = A;
|
||||
var CC : typeof C = B;
|
||||
~~
|
||||
!!! error TS2322: Type 'typeof B' is not assignable to type 'typeof C'.
|
||||
!!! error TS2322: Cannot assign an abstract constructor type to a non-abstract constructor type.
|
||||
|
||||
new AA;
|
||||
new BB;
|
||||
~~~~~~
|
||||
!!! error TS2511: Cannot create an instance of the abstract class 'B'.
|
||||
new CC;
|
||||
@ -0,0 +1,47 @@
|
||||
//// [classAbstractConstructorAssignability.ts]
|
||||
|
||||
class A {}
|
||||
|
||||
abstract class B extends A {}
|
||||
|
||||
class C extends B {}
|
||||
|
||||
var AA : typeof A = B;
|
||||
var BB : typeof B = A;
|
||||
var CC : typeof C = B;
|
||||
|
||||
new AA;
|
||||
new BB;
|
||||
new CC;
|
||||
|
||||
//// [classAbstractConstructorAssignability.js]
|
||||
var __extends = (this && this.__extends) || function (d, b) {
|
||||
for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
|
||||
function __() { this.constructor = d; }
|
||||
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
||||
};
|
||||
var A = (function () {
|
||||
function A() {
|
||||
}
|
||||
return A;
|
||||
})();
|
||||
var B = (function (_super) {
|
||||
__extends(B, _super);
|
||||
function B() {
|
||||
_super.apply(this, arguments);
|
||||
}
|
||||
return B;
|
||||
})(A);
|
||||
var C = (function (_super) {
|
||||
__extends(C, _super);
|
||||
function C() {
|
||||
_super.apply(this, arguments);
|
||||
}
|
||||
return C;
|
||||
})(B);
|
||||
var AA = B;
|
||||
var BB = A;
|
||||
var CC = B;
|
||||
new AA;
|
||||
new BB;
|
||||
new CC;
|
||||
22
tests/baselines/reference/classAbstractExtends.errors.txt
Normal file
22
tests/baselines/reference/classAbstractExtends.errors.txt
Normal file
@ -0,0 +1,22 @@
|
||||
tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractExtends.ts(10,7): error TS2515: Non-abstract class 'C' does not implement inherited abstract member 'bar' from class 'B'.
|
||||
|
||||
|
||||
==== tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractExtends.ts (1 errors) ====
|
||||
|
||||
class A {
|
||||
foo() {}
|
||||
}
|
||||
|
||||
abstract class B extends A {
|
||||
abstract bar();
|
||||
}
|
||||
|
||||
class C extends B { }
|
||||
~
|
||||
!!! error TS2515: Non-abstract class 'C' does not implement inherited abstract member 'bar' from class 'B'.
|
||||
|
||||
abstract class D extends B {}
|
||||
|
||||
class E extends B {
|
||||
bar() {}
|
||||
}
|
||||
59
tests/baselines/reference/classAbstractExtends.js
Normal file
59
tests/baselines/reference/classAbstractExtends.js
Normal file
@ -0,0 +1,59 @@
|
||||
//// [classAbstractExtends.ts]
|
||||
|
||||
class A {
|
||||
foo() {}
|
||||
}
|
||||
|
||||
abstract class B extends A {
|
||||
abstract bar();
|
||||
}
|
||||
|
||||
class C extends B { }
|
||||
|
||||
abstract class D extends B {}
|
||||
|
||||
class E extends B {
|
||||
bar() {}
|
||||
}
|
||||
|
||||
//// [classAbstractExtends.js]
|
||||
var __extends = (this && this.__extends) || function (d, b) {
|
||||
for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
|
||||
function __() { this.constructor = d; }
|
||||
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
||||
};
|
||||
var A = (function () {
|
||||
function A() {
|
||||
}
|
||||
A.prototype.foo = function () { };
|
||||
return A;
|
||||
})();
|
||||
var B = (function (_super) {
|
||||
__extends(B, _super);
|
||||
function B() {
|
||||
_super.apply(this, arguments);
|
||||
}
|
||||
return B;
|
||||
})(A);
|
||||
var C = (function (_super) {
|
||||
__extends(C, _super);
|
||||
function C() {
|
||||
_super.apply(this, arguments);
|
||||
}
|
||||
return C;
|
||||
})(B);
|
||||
var D = (function (_super) {
|
||||
__extends(D, _super);
|
||||
function D() {
|
||||
_super.apply(this, arguments);
|
||||
}
|
||||
return D;
|
||||
})(B);
|
||||
var E = (function (_super) {
|
||||
__extends(E, _super);
|
||||
function E() {
|
||||
_super.apply(this, arguments);
|
||||
}
|
||||
E.prototype.bar = function () { };
|
||||
return E;
|
||||
})(B);
|
||||
@ -0,0 +1,28 @@
|
||||
tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractFactoryFunction.ts(10,12): error TS2511: Cannot create an instance of the abstract class 'B'.
|
||||
tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractFactoryFunction.ts(14,6): error TS2345: Argument of type 'typeof B' is not assignable to parameter of type 'typeof A'.
|
||||
Cannot assign an abstract constructor type to a non-abstract constructor type.
|
||||
|
||||
|
||||
==== tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractFactoryFunction.ts (2 errors) ====
|
||||
|
||||
class A {}
|
||||
abstract class B extends A {}
|
||||
|
||||
function NewA(Factory: typeof A) {
|
||||
return new A;
|
||||
}
|
||||
|
||||
function NewB(Factory: typeof B) {
|
||||
return new B;
|
||||
~~~~~
|
||||
!!! error TS2511: Cannot create an instance of the abstract class 'B'.
|
||||
}
|
||||
|
||||
NewA(A);
|
||||
NewA(B);
|
||||
~
|
||||
!!! error TS2345: Argument of type 'typeof B' is not assignable to parameter of type 'typeof A'.
|
||||
!!! error TS2345: Cannot assign an abstract constructor type to a non-abstract constructor type.
|
||||
|
||||
NewB(A);
|
||||
NewB(B);
|
||||
47
tests/baselines/reference/classAbstractFactoryFunction.js
Normal file
47
tests/baselines/reference/classAbstractFactoryFunction.js
Normal file
@ -0,0 +1,47 @@
|
||||
//// [classAbstractFactoryFunction.ts]
|
||||
|
||||
class A {}
|
||||
abstract class B extends A {}
|
||||
|
||||
function NewA(Factory: typeof A) {
|
||||
return new A;
|
||||
}
|
||||
|
||||
function NewB(Factory: typeof B) {
|
||||
return new B;
|
||||
}
|
||||
|
||||
NewA(A);
|
||||
NewA(B);
|
||||
|
||||
NewB(A);
|
||||
NewB(B);
|
||||
|
||||
//// [classAbstractFactoryFunction.js]
|
||||
var __extends = (this && this.__extends) || function (d, b) {
|
||||
for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
|
||||
function __() { this.constructor = d; }
|
||||
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
||||
};
|
||||
var A = (function () {
|
||||
function A() {
|
||||
}
|
||||
return A;
|
||||
})();
|
||||
var B = (function (_super) {
|
||||
__extends(B, _super);
|
||||
function B() {
|
||||
_super.apply(this, arguments);
|
||||
}
|
||||
return B;
|
||||
})(A);
|
||||
function NewA(Factory) {
|
||||
return new A;
|
||||
}
|
||||
function NewB(Factory) {
|
||||
return new B;
|
||||
}
|
||||
NewA(A);
|
||||
NewA(B);
|
||||
NewB(A);
|
||||
NewB(B);
|
||||
@ -1,10 +1,14 @@
|
||||
tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractInstantiations1.ts(8,1): error TS2511: Cannot create an instance of the abstract class 'A'.
|
||||
tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractInstantiations1.ts(9,1): error TS2511: Cannot create an instance of the abstract class 'A'.
|
||||
tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractInstantiations1.ts(11,1): error TS2511: Cannot create an instance of the abstract class 'C'.
|
||||
tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractInstantiations1.ts(12,1): error TS2511: Cannot create an instance of the abstract class 'A'.
|
||||
tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractInstantiations1.ts(13,1): error TS2511: Cannot create an instance of the abstract class 'A'.
|
||||
tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractInstantiations1.ts(15,1): error TS2511: Cannot create an instance of the abstract class 'C'.
|
||||
|
||||
|
||||
==== tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractInstantiations1.ts (3 errors) ====
|
||||
|
||||
//
|
||||
// Calling new with (non)abstract classes.
|
||||
//
|
||||
|
||||
abstract class A {}
|
||||
|
||||
class B extends A {}
|
||||
|
||||
@ -1,5 +1,9 @@
|
||||
//// [classAbstractInstantiations1.ts]
|
||||
|
||||
//
|
||||
// Calling new with (non)abstract classes.
|
||||
//
|
||||
|
||||
abstract class A {}
|
||||
|
||||
class B extends A {}
|
||||
@ -21,6 +25,9 @@ c = new B;
|
||||
|
||||
|
||||
//// [classAbstractInstantiations1.js]
|
||||
//
|
||||
// Calling new with (non)abstract classes.
|
||||
//
|
||||
var __extends = (this && this.__extends) || function (d, b) {
|
||||
for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
|
||||
function __() { this.constructor = d; }
|
||||
|
||||
@ -1,4 +1,6 @@
|
||||
tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractInstantiations2.ts(10,1): error TS2511: Cannot create an instance of the abstract class 'B'.
|
||||
tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractInstantiations2.ts(13,5): error TS2322: Type 'typeof B' is not assignable to type 'typeof A'.
|
||||
Cannot assign an abstract constructor type to a non-abstract constructor type.
|
||||
tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractInstantiations2.ts(17,5): error TS2511: Cannot create an instance of the abstract class 'B'.
|
||||
tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractInstantiations2.ts(21,1): error TS2511: Cannot create an instance of the abstract class 'B'.
|
||||
tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractInstantiations2.ts(26,7): error TS2515: Non-abstract class 'C' does not implement inherited abstract member 'bar' from class 'B'.
|
||||
@ -7,7 +9,7 @@ tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbst
|
||||
tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractInstantiations2.ts(50,5): error TS1244: Abstract methods can only appear within an abstract class.
|
||||
|
||||
|
||||
==== tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractInstantiations2.ts (7 errors) ====
|
||||
==== tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractInstantiations2.ts (8 errors) ====
|
||||
class A {
|
||||
// ...
|
||||
}
|
||||
@ -23,6 +25,9 @@ tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbst
|
||||
|
||||
var BB: typeof B = B;
|
||||
var AA: typeof A = BB; // error, AA is not of abstract type.
|
||||
~~
|
||||
!!! error TS2322: Type 'typeof B' is not assignable to type 'typeof A'.
|
||||
!!! error TS2322: Cannot assign an abstract constructor type to a non-abstract constructor type.
|
||||
new AA;
|
||||
|
||||
function constructB(Factory : typeof B) {
|
||||
|
||||
@ -0,0 +1,19 @@
|
||||
tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractMethodInNonAbstractClass.ts(2,5): error TS1244: Abstract methods can only appear within an abstract class.
|
||||
tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractMethodInNonAbstractClass.ts(6,5): error TS1244: Abstract methods can only appear within an abstract class.
|
||||
tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractMethodInNonAbstractClass.ts(6,5): error TS1245: Method 'foo' cannot have an implementation because it is marked abstract.
|
||||
|
||||
|
||||
==== tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractMethodInNonAbstractClass.ts (3 errors) ====
|
||||
class A {
|
||||
abstract foo();
|
||||
~~~~~~~~
|
||||
!!! error TS1244: Abstract methods can only appear within an abstract class.
|
||||
}
|
||||
|
||||
class B {
|
||||
abstract foo() {}
|
||||
~~~~~~~~
|
||||
!!! error TS1244: Abstract methods can only appear within an abstract class.
|
||||
~~~~~~~~~~~~~~~~~
|
||||
!!! error TS1245: Method 'foo' cannot have an implementation because it is marked abstract.
|
||||
}
|
||||
@ -0,0 +1,21 @@
|
||||
//// [classAbstractMethodInNonAbstractClass.ts]
|
||||
class A {
|
||||
abstract foo();
|
||||
}
|
||||
|
||||
class B {
|
||||
abstract foo() {}
|
||||
}
|
||||
|
||||
//// [classAbstractMethodInNonAbstractClass.js]
|
||||
var A = (function () {
|
||||
function A() {
|
||||
}
|
||||
return A;
|
||||
})();
|
||||
var B = (function () {
|
||||
function B() {
|
||||
}
|
||||
B.prototype.foo = function () { };
|
||||
return B;
|
||||
})();
|
||||
@ -0,0 +1,29 @@
|
||||
tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractOverrideWithAbstract.ts(19,7): error TS2515: Non-abstract class 'CC' does not implement inherited abstract member 'foo' from class 'BB'.
|
||||
|
||||
|
||||
==== tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractOverrideWithAbstract.ts (1 errors) ====
|
||||
class A {
|
||||
foo() {}
|
||||
}
|
||||
|
||||
abstract class B extends A {
|
||||
abstract foo();
|
||||
}
|
||||
|
||||
abstract class AA {
|
||||
foo() {}
|
||||
abstract bar();
|
||||
}
|
||||
|
||||
abstract class BB extends AA {
|
||||
abstract foo();
|
||||
bar () {}
|
||||
}
|
||||
|
||||
class CC extends BB {} // error
|
||||
~~
|
||||
!!! error TS2515: Non-abstract class 'CC' does not implement inherited abstract member 'foo' from class 'BB'.
|
||||
|
||||
class DD extends BB {
|
||||
foo() {}
|
||||
}
|
||||
@ -0,0 +1,73 @@
|
||||
//// [classAbstractOverrideWithAbstract.ts]
|
||||
class A {
|
||||
foo() {}
|
||||
}
|
||||
|
||||
abstract class B extends A {
|
||||
abstract foo();
|
||||
}
|
||||
|
||||
abstract class AA {
|
||||
foo() {}
|
||||
abstract bar();
|
||||
}
|
||||
|
||||
abstract class BB extends AA {
|
||||
abstract foo();
|
||||
bar () {}
|
||||
}
|
||||
|
||||
class CC extends BB {} // error
|
||||
|
||||
class DD extends BB {
|
||||
foo() {}
|
||||
}
|
||||
|
||||
//// [classAbstractOverrideWithAbstract.js]
|
||||
var __extends = (this && this.__extends) || function (d, b) {
|
||||
for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
|
||||
function __() { this.constructor = d; }
|
||||
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
||||
};
|
||||
var A = (function () {
|
||||
function A() {
|
||||
}
|
||||
A.prototype.foo = function () { };
|
||||
return A;
|
||||
})();
|
||||
var B = (function (_super) {
|
||||
__extends(B, _super);
|
||||
function B() {
|
||||
_super.apply(this, arguments);
|
||||
}
|
||||
return B;
|
||||
})(A);
|
||||
var AA = (function () {
|
||||
function AA() {
|
||||
}
|
||||
AA.prototype.foo = function () { };
|
||||
return AA;
|
||||
})();
|
||||
var BB = (function (_super) {
|
||||
__extends(BB, _super);
|
||||
function BB() {
|
||||
_super.apply(this, arguments);
|
||||
}
|
||||
BB.prototype.bar = function () { };
|
||||
return BB;
|
||||
})(AA);
|
||||
var CC = (function (_super) {
|
||||
__extends(CC, _super);
|
||||
function CC() {
|
||||
_super.apply(this, arguments);
|
||||
}
|
||||
return CC;
|
||||
})(BB); // error
|
||||
var DD = (function (_super) {
|
||||
__extends(DD, _super);
|
||||
function DD() {
|
||||
_super.apply(this, arguments);
|
||||
}
|
||||
DD.prototype.foo = function () { };
|
||||
return DD;
|
||||
})(BB);
|
||||
@ -0,0 +1,23 @@
|
||||
interface I {
|
||||
x: number;
|
||||
}
|
||||
|
||||
interface IConstructor {
|
||||
new (): I;
|
||||
|
||||
y: number;
|
||||
prototype: I;
|
||||
}
|
||||
|
||||
var I: IConstructor;
|
||||
|
||||
abstract class A {
|
||||
x: number;
|
||||
static y: number;
|
||||
}
|
||||
|
||||
var AA: typeof A;
|
||||
AA = I;
|
||||
|
||||
var AAA: typeof I;
|
||||
AAA = A;
|
||||
@ -0,0 +1,14 @@
|
||||
|
||||
class A {}
|
||||
|
||||
abstract class B extends A {}
|
||||
|
||||
class C extends B {}
|
||||
|
||||
var AA : typeof A = B;
|
||||
var BB : typeof B = A;
|
||||
var CC : typeof C = B;
|
||||
|
||||
new AA;
|
||||
new BB;
|
||||
new CC;
|
||||
@ -0,0 +1,16 @@
|
||||
|
||||
class A {
|
||||
foo() {}
|
||||
}
|
||||
|
||||
abstract class B extends A {
|
||||
abstract bar();
|
||||
}
|
||||
|
||||
class C extends B { }
|
||||
|
||||
abstract class D extends B {}
|
||||
|
||||
class E extends B {
|
||||
bar() {}
|
||||
}
|
||||
@ -0,0 +1,17 @@
|
||||
|
||||
class A {}
|
||||
abstract class B extends A {}
|
||||
|
||||
function NewA(Factory: typeof A) {
|
||||
return new A;
|
||||
}
|
||||
|
||||
function NewB(Factory: typeof B) {
|
||||
return new B;
|
||||
}
|
||||
|
||||
NewA(A);
|
||||
NewA(B);
|
||||
|
||||
NewB(A);
|
||||
NewB(B);
|
||||
@ -1,4 +1,8 @@
|
||||
|
||||
//
|
||||
// Calling new with (non)abstract classes.
|
||||
//
|
||||
|
||||
abstract class A {}
|
||||
|
||||
class B extends A {}
|
||||
|
||||
@ -0,0 +1,7 @@
|
||||
class A {
|
||||
abstract foo();
|
||||
}
|
||||
|
||||
class B {
|
||||
abstract foo() {}
|
||||
}
|
||||
@ -0,0 +1,23 @@
|
||||
class A {
|
||||
foo() {}
|
||||
}
|
||||
|
||||
abstract class B extends A {
|
||||
abstract foo();
|
||||
}
|
||||
|
||||
abstract class AA {
|
||||
foo() {}
|
||||
abstract bar();
|
||||
}
|
||||
|
||||
abstract class BB extends AA {
|
||||
abstract foo();
|
||||
bar () {}
|
||||
}
|
||||
|
||||
class CC extends BB {} // error
|
||||
|
||||
class DD extends BB {
|
||||
foo() {}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user