fix(60484): Implementing a prim type in a class expression should report error (#60490)

This commit is contained in:
Oleksandr T. 2024-11-20 05:45:22 +02:00 committed by GitHub
parent d6b7c41fbc
commit d85767abfd
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
11 changed files with 308 additions and 10 deletions

View File

@ -3458,10 +3458,10 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
if (containerKind === SyntaxKind.InterfaceDeclaration && heritageKind === SyntaxKind.ExtendsKeyword) {
error(errorLocation, Diagnostics.An_interface_cannot_extend_a_primitive_type_like_0_It_can_only_extend_other_named_object_types, unescapeLeadingUnderscores(name));
}
else if (containerKind === SyntaxKind.ClassDeclaration && heritageKind === SyntaxKind.ExtendsKeyword) {
else if (isClassLike(grandparent.parent) && heritageKind === SyntaxKind.ExtendsKeyword) {
error(errorLocation, Diagnostics.A_class_cannot_extend_a_primitive_type_like_0_Classes_can_only_extend_constructable_values, unescapeLeadingUnderscores(name));
}
else if (containerKind === SyntaxKind.ClassDeclaration && heritageKind === SyntaxKind.ImplementsKeyword) {
else if (isClassLike(grandparent.parent) && heritageKind === SyntaxKind.ImplementsKeyword) {
error(errorLocation, Diagnostics.A_class_cannot_implement_a_primitive_type_like_0_It_can_only_implement_other_named_object_types, unescapeLeadingUnderscores(name));
}
}

View File

@ -7,9 +7,15 @@ classExtendingPrimitive.ts(8,18): error TS2304: Cannot find name 'Null'.
classExtendingPrimitive.ts(10,18): error TS2507: Type 'undefined' is not a constructor function type.
classExtendingPrimitive.ts(11,18): error TS2552: Cannot find name 'Undefined'. Did you mean 'undefined'?
classExtendingPrimitive.ts(14,18): error TS2507: Type 'typeof E' is not a constructor function type.
classExtendingPrimitive.ts(16,26): error TS2863: A class cannot extend a primitive type like 'number'. Classes can only extend constructable values.
classExtendingPrimitive.ts(17,27): error TS2863: A class cannot extend a primitive type like 'string'. Classes can only extend constructable values.
classExtendingPrimitive.ts(18,27): error TS2863: A class cannot extend a primitive type like 'boolean'. Classes can only extend constructable values.
classExtendingPrimitive.ts(20,29): error TS2863: A class cannot extend a primitive type like 'number'. Classes can only extend constructable values.
classExtendingPrimitive.ts(21,29): error TS2863: A class cannot extend a primitive type like 'string'. Classes can only extend constructable values.
classExtendingPrimitive.ts(22,29): error TS2863: A class cannot extend a primitive type like 'boolean'. Classes can only extend constructable values.
==== classExtendingPrimitive.ts (9 errors) ====
==== classExtendingPrimitive.ts (15 errors) ====
// classes cannot extend primitives
class C extends number { }
@ -41,4 +47,25 @@ classExtendingPrimitive.ts(14,18): error TS2507: Type 'typeof E' is not a constr
enum E { A }
class C8 extends E { }
~
!!! error TS2507: Type 'typeof E' is not a constructor function type.
!!! error TS2507: Type 'typeof E' is not a constructor function type.
const C9 = class extends number { }
~~~~~~
!!! error TS2863: A class cannot extend a primitive type like 'number'. Classes can only extend constructable values.
const C10 = class extends string { }
~~~~~~
!!! error TS2863: A class cannot extend a primitive type like 'string'. Classes can only extend constructable values.
const C11 = class extends boolean { }
~~~~~~~
!!! error TS2863: A class cannot extend a primitive type like 'boolean'. Classes can only extend constructable values.
const C12 = class A extends number { }
~~~~~~
!!! error TS2863: A class cannot extend a primitive type like 'number'. Classes can only extend constructable values.
const C13 = class B extends string { }
~~~~~~
!!! error TS2863: A class cannot extend a primitive type like 'string'. Classes can only extend constructable values.
const C14 = class C extends boolean { }
~~~~~~~
!!! error TS2863: A class cannot extend a primitive type like 'boolean'. Classes can only extend constructable values.

View File

@ -14,7 +14,16 @@ class C6 extends undefined { }
class C7 extends Undefined { }
enum E { A }
class C8 extends E { }
class C8 extends E { }
const C9 = class extends number { }
const C10 = class extends string { }
const C11 = class extends boolean { }
const C12 = class A extends number { }
const C13 = class B extends string { }
const C14 = class C extends boolean { }
//// [classExtendingPrimitive.js]
// classes cannot extend primitives
@ -105,3 +114,45 @@ var C8 = /** @class */ (function (_super) {
}
return C8;
}(E));
var C9 = /** @class */ (function (_super) {
__extends(C9, _super);
function C9() {
return _super !== null && _super.apply(this, arguments) || this;
}
return C9;
}(number));
var C10 = /** @class */ (function (_super) {
__extends(C10, _super);
function C10() {
return _super !== null && _super.apply(this, arguments) || this;
}
return C10;
}(string));
var C11 = /** @class */ (function (_super) {
__extends(C11, _super);
function C11() {
return _super !== null && _super.apply(this, arguments) || this;
}
return C11;
}(boolean));
var C12 = /** @class */ (function (_super) {
__extends(A, _super);
function A() {
return _super !== null && _super.apply(this, arguments) || this;
}
return A;
}(number));
var C13 = /** @class */ (function (_super) {
__extends(B, _super);
function B() {
return _super !== null && _super.apply(this, arguments) || this;
}
return B;
}(string));
var C14 = /** @class */ (function (_super) {
__extends(C, _super);
function C() {
return _super !== null && _super.apply(this, arguments) || this;
}
return C;
}(boolean));

View File

@ -39,3 +39,24 @@ class C8 extends E { }
>C8 : Symbol(C8, Decl(classExtendingPrimitive.ts, 12, 12))
>E : Symbol(E, Decl(classExtendingPrimitive.ts, 10, 30))
const C9 = class extends number { }
>C9 : Symbol(C9, Decl(classExtendingPrimitive.ts, 15, 5))
const C10 = class extends string { }
>C10 : Symbol(C10, Decl(classExtendingPrimitive.ts, 16, 5))
const C11 = class extends boolean { }
>C11 : Symbol(C11, Decl(classExtendingPrimitive.ts, 17, 5))
const C12 = class A extends number { }
>C12 : Symbol(C12, Decl(classExtendingPrimitive.ts, 19, 5))
>A : Symbol(A, Decl(classExtendingPrimitive.ts, 19, 11))
const C13 = class B extends string { }
>C13 : Symbol(C13, Decl(classExtendingPrimitive.ts, 20, 5))
>B : Symbol(B, Decl(classExtendingPrimitive.ts, 20, 11))
const C14 = class C extends boolean { }
>C14 : Symbol(C14, Decl(classExtendingPrimitive.ts, 21, 5))
>C : Symbol(C, Decl(classExtendingPrimitive.ts, 21, 11))

View File

@ -69,3 +69,57 @@ class C8 extends E { }
>E : typeof E
> : ^^^^^^^^
const C9 = class extends number { }
>C9 : typeof C9
> : ^^^^^^^^^
>class extends number { } : typeof C9
> : ^^^^^^^^^
>number : any
> : ^^^
const C10 = class extends string { }
>C10 : typeof C10
> : ^^^^^^^^^^
>class extends string { } : typeof C10
> : ^^^^^^^^^^
>string : any
> : ^^^
const C11 = class extends boolean { }
>C11 : typeof C11
> : ^^^^^^^^^^
>class extends boolean { } : typeof C11
> : ^^^^^^^^^^
>boolean : any
> : ^^^
const C12 = class A extends number { }
>C12 : typeof A
> : ^^^^^^^^
>class A extends number { } : typeof A
> : ^^^^^^^^
>A : typeof A
> : ^^^^^^^^
>number : any
> : ^^^
const C13 = class B extends string { }
>C13 : typeof B
> : ^^^^^^^^
>class B extends string { } : typeof B
> : ^^^^^^^^
>B : typeof B
> : ^^^^^^^^
>string : any
> : ^^^
const C14 = class C extends boolean { }
>C14 : typeof C
> : ^^^^^^^^
>class C extends boolean { } : typeof C
> : ^^^^^^^^
>C : typeof C
> : ^^^^^^^^
>boolean : any
> : ^^^

View File

@ -1,9 +1,15 @@
classImplementsPrimitive.ts(3,20): error TS2864: A class cannot implement a primitive type like 'number'. It can only implement other named object types.
classImplementsPrimitive.ts(4,21): error TS2864: A class cannot implement a primitive type like 'string'. It can only implement other named object types.
classImplementsPrimitive.ts(5,21): error TS2864: A class cannot implement a primitive type like 'boolean'. It can only implement other named object types.
classImplementsPrimitive.ts(7,29): error TS2864: A class cannot implement a primitive type like 'number'. It can only implement other named object types.
classImplementsPrimitive.ts(8,29): error TS2864: A class cannot implement a primitive type like 'string'. It can only implement other named object types.
classImplementsPrimitive.ts(9,29): error TS2864: A class cannot implement a primitive type like 'boolean'. It can only implement other named object types.
classImplementsPrimitive.ts(11,31): error TS2864: A class cannot implement a primitive type like 'number'. It can only implement other named object types.
classImplementsPrimitive.ts(12,31): error TS2864: A class cannot implement a primitive type like 'string'. It can only implement other named object types.
classImplementsPrimitive.ts(13,31): error TS2864: A class cannot implement a primitive type like 'boolean'. It can only implement other named object types.
==== classImplementsPrimitive.ts (3 errors) ====
==== classImplementsPrimitive.ts (9 errors) ====
// classes cannot implement primitives
class C implements number { }
@ -14,4 +20,25 @@ classImplementsPrimitive.ts(5,21): error TS2864: A class cannot implement a prim
!!! error TS2864: A class cannot implement a primitive type like 'string'. It can only implement other named object types.
class C3 implements boolean { }
~~~~~~~
!!! error TS2864: A class cannot implement a primitive type like 'boolean'. It can only implement other named object types.
!!! error TS2864: A class cannot implement a primitive type like 'boolean'. It can only implement other named object types.
const C4 = class implements number {}
~~~~~~
!!! error TS2864: A class cannot implement a primitive type like 'number'. It can only implement other named object types.
const C5 = class implements string {}
~~~~~~
!!! error TS2864: A class cannot implement a primitive type like 'string'. It can only implement other named object types.
const C6 = class implements boolean {}
~~~~~~~
!!! error TS2864: A class cannot implement a primitive type like 'boolean'. It can only implement other named object types.
const C7 = class A implements number { }
~~~~~~
!!! error TS2864: A class cannot implement a primitive type like 'number'. It can only implement other named object types.
const C8 = class B implements string { }
~~~~~~
!!! error TS2864: A class cannot implement a primitive type like 'string'. It can only implement other named object types.
const C9 = class C implements boolean { }
~~~~~~~
!!! error TS2864: A class cannot implement a primitive type like 'boolean'. It can only implement other named object types.

View File

@ -5,7 +5,16 @@
class C implements number { }
class C2 implements string { }
class C3 implements boolean { }
class C3 implements boolean { }
const C4 = class implements number {}
const C5 = class implements string {}
const C6 = class implements boolean {}
const C7 = class A implements number { }
const C8 = class B implements string { }
const C9 = class C implements boolean { }
//// [classImplementsPrimitive.js]
// classes cannot implement primitives
@ -24,3 +33,33 @@ var C3 = /** @class */ (function () {
}
return C3;
}());
var C4 = /** @class */ (function () {
function class_1() {
}
return class_1;
}());
var C5 = /** @class */ (function () {
function class_2() {
}
return class_2;
}());
var C6 = /** @class */ (function () {
function class_3() {
}
return class_3;
}());
var C7 = /** @class */ (function () {
function A() {
}
return A;
}());
var C8 = /** @class */ (function () {
function B() {
}
return B;
}());
var C9 = /** @class */ (function () {
function C() {
}
return C;
}());

View File

@ -12,3 +12,24 @@ class C2 implements string { }
class C3 implements boolean { }
>C3 : Symbol(C3, Decl(classImplementsPrimitive.ts, 3, 30))
const C4 = class implements number {}
>C4 : Symbol(C4, Decl(classImplementsPrimitive.ts, 6, 5))
const C5 = class implements string {}
>C5 : Symbol(C5, Decl(classImplementsPrimitive.ts, 7, 5))
const C6 = class implements boolean {}
>C6 : Symbol(C6, Decl(classImplementsPrimitive.ts, 8, 5))
const C7 = class A implements number { }
>C7 : Symbol(C7, Decl(classImplementsPrimitive.ts, 10, 5))
>A : Symbol(A, Decl(classImplementsPrimitive.ts, 10, 10))
const C8 = class B implements string { }
>C8 : Symbol(C8, Decl(classImplementsPrimitive.ts, 11, 5))
>B : Symbol(B, Decl(classImplementsPrimitive.ts, 11, 10))
const C9 = class C implements boolean { }
>C9 : Symbol(C9, Decl(classImplementsPrimitive.ts, 12, 5))
>C : Symbol(C, Decl(classImplementsPrimitive.ts, 12, 10))

View File

@ -15,3 +15,45 @@ class C3 implements boolean { }
>C3 : C3
> : ^^
const C4 = class implements number {}
>C4 : typeof C4
> : ^^^^^^^^^
>class implements number {} : typeof C4
> : ^^^^^^^^^
const C5 = class implements string {}
>C5 : typeof C5
> : ^^^^^^^^^
>class implements string {} : typeof C5
> : ^^^^^^^^^
const C6 = class implements boolean {}
>C6 : typeof C6
> : ^^^^^^^^^
>class implements boolean {} : typeof C6
> : ^^^^^^^^^
const C7 = class A implements number { }
>C7 : typeof A
> : ^^^^^^^^
>class A implements number { } : typeof A
> : ^^^^^^^^
>A : typeof A
> : ^^^^^^^^
const C8 = class B implements string { }
>C8 : typeof B
> : ^^^^^^^^
>class B implements string { } : typeof B
> : ^^^^^^^^
>B : typeof B
> : ^^^^^^^^
const C9 = class C implements boolean { }
>C9 : typeof C
> : ^^^^^^^^
>class C implements boolean { } : typeof C
> : ^^^^^^^^
>C : typeof C
> : ^^^^^^^^

View File

@ -2,4 +2,12 @@
class C implements number { }
class C2 implements string { }
class C3 implements boolean { }
class C3 implements boolean { }
const C4 = class implements number {}
const C5 = class implements string {}
const C6 = class implements boolean {}
const C7 = class A implements number { }
const C8 = class B implements string { }
const C9 = class C implements boolean { }

View File

@ -11,4 +11,12 @@ class C6 extends undefined { }
class C7 extends Undefined { }
enum E { A }
class C8 extends E { }
class C8 extends E { }
const C9 = class extends number { }
const C10 = class extends string { }
const C11 = class extends boolean { }
const C12 = class A extends number { }
const C13 = class B extends string { }
const C14 = class C extends boolean { }