mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-02-04 21:53:42 -06:00
Consistently return errorType for super expressions in classes that extend null (#55506)
This commit is contained in:
parent
58650d97c5
commit
e9af22ace9
@ -12069,7 +12069,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
/**
|
||||
* The base constructor of a class can resolve to
|
||||
* * undefinedType if the class has no extends clause,
|
||||
* * unknownType if an error occurred during resolution of the extends expression,
|
||||
* * errorType if an error occurred during resolution of the extends expression,
|
||||
* * nullType if the extends expression is the null value,
|
||||
* * anyType if the extends expression has type any, or
|
||||
* * an object type with at least one construct signature.
|
||||
@ -28817,7 +28817,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
* Otherwise, return false
|
||||
* @param classDecl a class declaration to check if it extends null
|
||||
*/
|
||||
function classDeclarationExtendsNull(classDecl: ClassDeclaration): boolean {
|
||||
function classDeclarationExtendsNull(classDecl: ClassLikeDeclaration): boolean {
|
||||
const classSymbol = getSymbolOfDeclaration(classDecl);
|
||||
const classInstanceType = getDeclaredTypeOfSymbol(classSymbol) as InterfaceType;
|
||||
const baseConstructorType = getBaseConstructorTypeOfClass(classInstanceType);
|
||||
@ -29227,6 +29227,10 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
return errorType;
|
||||
}
|
||||
|
||||
if (classDeclarationExtendsNull(classLikeDeclaration)) {
|
||||
return isCallExpression ? errorType : nullWideningType;
|
||||
}
|
||||
|
||||
const classType = getDeclaredTypeOfSymbol(getSymbolOfDeclaration(classLikeDeclaration)) as InterfaceType;
|
||||
const baseClassType = classType && getBaseTypes(classType)[0];
|
||||
if (!baseClassType) {
|
||||
@ -39277,7 +39281,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
// TS 1.0 spec (April 2014): 8.3.2
|
||||
// Constructors of classes with no extends clause may not contain super calls, whereas
|
||||
// constructors of derived classes must contain at least one super call somewhere in their function body.
|
||||
const containingClassDecl = node.parent as ClassDeclaration;
|
||||
const containingClassDecl = node.parent;
|
||||
if (getClassExtendsHeritageElement(containingClassDecl)) {
|
||||
captureLexicalThis(node.parent, containingClassDecl);
|
||||
const classExtendsNull = classDeclarationExtendsNull(containingClassDecl);
|
||||
@ -39293,7 +39297,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
// or the containing class declares instance member variables with initializers.
|
||||
|
||||
const superCallShouldBeRootLevel = !emitStandardClassFields &&
|
||||
(some((node.parent as ClassDeclaration).members, isInstancePropertyWithInitializerOrPrivateIdentifierProperty) ||
|
||||
(some(node.parent.members, isInstancePropertyWithInitializerOrPrivateIdentifierProperty) ||
|
||||
some(node.parameters, p => hasSyntacticModifier(p, ModifierFlags.ParameterPropertyModifier)));
|
||||
|
||||
if (superCallShouldBeRootLevel) {
|
||||
|
||||
20
tests/baselines/reference/classExtendsNull2.errors.txt
Normal file
20
tests/baselines/reference/classExtendsNull2.errors.txt
Normal file
@ -0,0 +1,20 @@
|
||||
classExtendsNull2.ts(5,7): error TS2417: Class static side 'typeof C' incorrectly extends base class static side 'null'.
|
||||
classExtendsNull2.ts(7,5): error TS17005: A constructor cannot contain a 'super' call when its class extends 'null'.
|
||||
|
||||
|
||||
==== classExtendsNull2.ts (2 errors) ====
|
||||
// https://github.com/microsoft/TypeScript/issues/55499
|
||||
|
||||
interface Base {}
|
||||
|
||||
class C extends null {
|
||||
~
|
||||
!!! error TS2417: Class static side 'typeof C' incorrectly extends base class static side 'null'.
|
||||
constructor() {
|
||||
super();
|
||||
~~~~~~~
|
||||
!!! error TS17005: A constructor cannot contain a 'super' call when its class extends 'null'.
|
||||
}
|
||||
}
|
||||
interface C extends Base {}
|
||||
|
||||
19
tests/baselines/reference/classExtendsNull2.symbols
Normal file
19
tests/baselines/reference/classExtendsNull2.symbols
Normal file
@ -0,0 +1,19 @@
|
||||
//// [tests/cases/compiler/classExtendsNull2.ts] ////
|
||||
|
||||
=== classExtendsNull2.ts ===
|
||||
// https://github.com/microsoft/TypeScript/issues/55499
|
||||
|
||||
interface Base {}
|
||||
>Base : Symbol(Base, Decl(classExtendsNull2.ts, 0, 0))
|
||||
|
||||
class C extends null {
|
||||
>C : Symbol(C, Decl(classExtendsNull2.ts, 2, 17), Decl(classExtendsNull2.ts, 8, 1))
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
}
|
||||
}
|
||||
interface C extends Base {}
|
||||
>C : Symbol(C, Decl(classExtendsNull2.ts, 2, 17), Decl(classExtendsNull2.ts, 8, 1))
|
||||
>Base : Symbol(Base, Decl(classExtendsNull2.ts, 0, 0))
|
||||
|
||||
18
tests/baselines/reference/classExtendsNull2.types
Normal file
18
tests/baselines/reference/classExtendsNull2.types
Normal file
@ -0,0 +1,18 @@
|
||||
//// [tests/cases/compiler/classExtendsNull2.ts] ////
|
||||
|
||||
=== classExtendsNull2.ts ===
|
||||
// https://github.com/microsoft/TypeScript/issues/55499
|
||||
|
||||
interface Base {}
|
||||
|
||||
class C extends null {
|
||||
>C : C
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
>super() : void
|
||||
>super : any
|
||||
}
|
||||
}
|
||||
interface C extends Base {}
|
||||
|
||||
20
tests/baselines/reference/classExtendsNull3.errors.txt
Normal file
20
tests/baselines/reference/classExtendsNull3.errors.txt
Normal file
@ -0,0 +1,20 @@
|
||||
classExtendsNull3.ts(3,5): error TS2531: Object is possibly 'null'.
|
||||
classExtendsNull3.ts(9,5): error TS2531: Object is possibly 'null'.
|
||||
|
||||
|
||||
==== classExtendsNull3.ts (2 errors) ====
|
||||
class C1 extends null {
|
||||
static method() {
|
||||
super.oops;
|
||||
~~~~~
|
||||
!!! error TS2531: Object is possibly 'null'.
|
||||
}
|
||||
}
|
||||
|
||||
class C2 extends null {
|
||||
method() {
|
||||
super.oops;
|
||||
~~~~~
|
||||
!!! error TS2531: Object is possibly 'null'.
|
||||
}
|
||||
}
|
||||
22
tests/baselines/reference/classExtendsNull3.symbols
Normal file
22
tests/baselines/reference/classExtendsNull3.symbols
Normal file
@ -0,0 +1,22 @@
|
||||
//// [tests/cases/compiler/classExtendsNull3.ts] ////
|
||||
|
||||
=== classExtendsNull3.ts ===
|
||||
class C1 extends null {
|
||||
>C1 : Symbol(C1, Decl(classExtendsNull3.ts, 0, 0))
|
||||
|
||||
static method() {
|
||||
>method : Symbol(C1.method, Decl(classExtendsNull3.ts, 0, 23))
|
||||
|
||||
super.oops;
|
||||
}
|
||||
}
|
||||
|
||||
class C2 extends null {
|
||||
>C2 : Symbol(C2, Decl(classExtendsNull3.ts, 4, 1))
|
||||
|
||||
method() {
|
||||
>method : Symbol(C2.method, Decl(classExtendsNull3.ts, 6, 23))
|
||||
|
||||
super.oops;
|
||||
}
|
||||
}
|
||||
28
tests/baselines/reference/classExtendsNull3.types
Normal file
28
tests/baselines/reference/classExtendsNull3.types
Normal file
@ -0,0 +1,28 @@
|
||||
//// [tests/cases/compiler/classExtendsNull3.ts] ////
|
||||
|
||||
=== classExtendsNull3.ts ===
|
||||
class C1 extends null {
|
||||
>C1 : C1
|
||||
|
||||
static method() {
|
||||
>method : () => void
|
||||
|
||||
super.oops;
|
||||
>super.oops : any
|
||||
>super : null
|
||||
>oops : any
|
||||
}
|
||||
}
|
||||
|
||||
class C2 extends null {
|
||||
>C2 : C2
|
||||
|
||||
method() {
|
||||
>method : () => void
|
||||
|
||||
super.oops;
|
||||
>super.oops : any
|
||||
>super : null
|
||||
>oops : any
|
||||
}
|
||||
}
|
||||
13
tests/cases/compiler/classExtendsNull2.ts
Normal file
13
tests/cases/compiler/classExtendsNull2.ts
Normal file
@ -0,0 +1,13 @@
|
||||
// @strict: true
|
||||
// @noEmit: true
|
||||
|
||||
// https://github.com/microsoft/TypeScript/issues/55499
|
||||
|
||||
interface Base {}
|
||||
|
||||
class C extends null {
|
||||
constructor() {
|
||||
super();
|
||||
}
|
||||
}
|
||||
interface C extends Base {}
|
||||
14
tests/cases/compiler/classExtendsNull3.ts
Normal file
14
tests/cases/compiler/classExtendsNull3.ts
Normal file
@ -0,0 +1,14 @@
|
||||
// @strict: true
|
||||
// @noEmit: true
|
||||
|
||||
class C1 extends null {
|
||||
static method() {
|
||||
super.oops;
|
||||
}
|
||||
}
|
||||
|
||||
class C2 extends null {
|
||||
method() {
|
||||
super.oops;
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user