mirror of
https://github.com/microsoft/TypeScript.git
synced 2025-11-18 17:21:48 +00:00
fix use-before-init error when targeting ES2022 (#55028)
This commit is contained in:
+13
-11
@@ -274,6 +274,7 @@ import {
|
||||
getEmitModuleKind,
|
||||
getEmitModuleResolutionKind,
|
||||
getEmitScriptTarget,
|
||||
getEmitStandardClassFields,
|
||||
getEnclosingBlockScopeContainer,
|
||||
getEnclosingContainer,
|
||||
getEntityNameFromTypeNode,
|
||||
@@ -1437,6 +1438,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
var moduleKind = getEmitModuleKind(compilerOptions);
|
||||
var legacyDecorators = !!compilerOptions.experimentalDecorators;
|
||||
var useDefineForClassFields = getUseDefineForClassFields(compilerOptions);
|
||||
var emitStandardClassFields = getEmitStandardClassFields(compilerOptions);
|
||||
var allowSyntheticDefaultImports = getAllowSyntheticDefaultImports(compilerOptions);
|
||||
var strictNullChecks = getStrictOptionValue(compilerOptions, "strictNullChecks");
|
||||
var strictFunctionTypes = getStrictOptionValue(compilerOptions, "strictFunctionTypes");
|
||||
@@ -2785,8 +2787,8 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
return !isPropertyImmediatelyReferencedWithinDeclaration(declaration, usage, /*stopAtAnyPropertyDeclaration*/ false);
|
||||
}
|
||||
else if (isParameterPropertyDeclaration(declaration, declaration.parent)) {
|
||||
// foo = this.bar is illegal in esnext+useDefineForClassFields when bar is a parameter property
|
||||
return !(getEmitScriptTarget(compilerOptions) === ScriptTarget.ESNext && useDefineForClassFields
|
||||
// foo = this.bar is illegal in emitStandardClassFields when bar is a parameter property
|
||||
return !(emitStandardClassFields
|
||||
&& getContainingClass(declaration) === getContainingClass(usage)
|
||||
&& isUsedInFunctionOrInstanceProperty(usage, declaration));
|
||||
}
|
||||
@@ -2798,7 +2800,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
// 1. inside an export specifier
|
||||
// 2. inside a function
|
||||
// 3. inside an instance property initializer, a reference to a non-instance property
|
||||
// (except when target: "esnext" and useDefineForClassFields: true and the reference is to a parameter property)
|
||||
// (except when emitStandardClassFields: true and the reference is to a parameter property)
|
||||
// 4. inside a static property initializer, a reference to a static method in the same class
|
||||
// 5. inside a TS export= declaration (since we will move the export statement during emit to avoid TDZ)
|
||||
// or if usage is in a type context:
|
||||
@@ -2817,7 +2819,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
return true;
|
||||
}
|
||||
if (isUsedInFunctionOrInstanceProperty(usage, declaration)) {
|
||||
if (getEmitScriptTarget(compilerOptions) >= ScriptTarget.ES2022 && useDefineForClassFields
|
||||
if (emitStandardClassFields
|
||||
&& getContainingClass(declaration)
|
||||
&& (isPropertyDeclaration(declaration) || isParameterPropertyDeclaration(declaration, declaration.parent))) {
|
||||
return !isPropertyImmediatelyReferencedWithinDeclaration(declaration, usage, /*stopAtAnyPropertyDeclaration*/ true);
|
||||
@@ -2974,7 +2976,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
case SyntaxKind.PropertyDeclaration:
|
||||
// static properties in classes introduce temporary variables
|
||||
if (hasStaticModifier(node)) {
|
||||
return target < ScriptTarget.ESNext || !useDefineForClassFields;
|
||||
return !emitStandardClassFields;
|
||||
}
|
||||
return requiresScopeChangeWorker((node as PropertyDeclaration).name);
|
||||
default:
|
||||
@@ -3392,10 +3394,10 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
// 1. When result is undefined, after checking for a missing "this."
|
||||
// 2. When result is defined
|
||||
function checkAndReportErrorForInvalidInitializer() {
|
||||
if (propertyWithInvalidInitializer && !(useDefineForClassFields && getEmitScriptTarget(compilerOptions) >= ScriptTarget.ES2022)) {
|
||||
if (propertyWithInvalidInitializer && !emitStandardClassFields) {
|
||||
// We have a match, but the reference occurred within a property initializer and the identifier also binds
|
||||
// to a local variable in the constructor where the code will be emitted. Note that this is actually allowed
|
||||
// with ESNext+useDefineForClassFields because the scope semantics are different.
|
||||
// with emitStandardClassFields because the scope semantics are different.
|
||||
error(errorLocation,
|
||||
errorLocation && propertyWithInvalidInitializer.type && textRangeContainsPositionInclusive(propertyWithInvalidInitializer.type, errorLocation.pos)
|
||||
? Diagnostics.Type_of_instance_member_variable_0_cannot_reference_identifier_1_declared_in_the_constructor
|
||||
@@ -31739,7 +31741,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
&& !(isAccessExpression(node) && isAccessExpression(node.expression))
|
||||
&& !isBlockScopedNameDeclaredBeforeUse(valueDeclaration, right)
|
||||
&& !(isMethodDeclaration(valueDeclaration) && getCombinedModifierFlagsCached(valueDeclaration) & ModifierFlags.Static)
|
||||
&& (compilerOptions.useDefineForClassFields || !isPropertyDeclaredInAncestorClass(prop))) {
|
||||
&& (useDefineForClassFields || !isPropertyDeclaredInAncestorClass(prop))) {
|
||||
diagnosticMessage = error(right, Diagnostics.Property_0_is_used_before_its_initialization, declarationName);
|
||||
}
|
||||
else if (valueDeclaration.kind === SyntaxKind.ClassDeclaration &&
|
||||
@@ -38453,7 +38455,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
case "length":
|
||||
case "caller":
|
||||
case "arguments":
|
||||
if (compilerOptions.useDefineForClassFields) {
|
||||
if (useDefineForClassFields) {
|
||||
break;
|
||||
}
|
||||
// fall through
|
||||
@@ -38658,7 +38660,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
// or the containing class declares instance member variables with initializers.
|
||||
|
||||
const superCallShouldBeRootLevel =
|
||||
(getEmitScriptTarget(compilerOptions) !== ScriptTarget.ESNext || !useDefineForClassFields) &&
|
||||
!emitStandardClassFields &&
|
||||
(some((node.parent as ClassDeclaration).members, isInstancePropertyWithInitializerOrPrivateIdentifierProperty) ||
|
||||
some(node.parameters, p => hasSyntacticModifier(p, ModifierFlags.ParameterPropertyModifier)));
|
||||
|
||||
@@ -42935,7 +42937,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
!legacyDecorators && languageVersion < ScriptTarget.ESNext &&
|
||||
classOrConstructorParameterIsDecorated(/*useLegacyDecorators*/ false, node);
|
||||
const willTransformPrivateElementsOrClassStaticBlocks = languageVersion <= ScriptTarget.ES2022;
|
||||
const willTransformInitializers = !useDefineForClassFields || languageVersion < ScriptTarget.ES2022;
|
||||
const willTransformInitializers = !emitStandardClassFields;
|
||||
if (willTransformStaticElementsOfDecoratedClass || willTransformPrivateElementsOrClassStaticBlocks) {
|
||||
for (const member of node.members) {
|
||||
if (willTransformStaticElementsOfDecoratedClass && classElementOrClassElementParameterIsDecorated(/*useLegacyDecorators*/ false, member, node)) {
|
||||
|
||||
@@ -8666,6 +8666,11 @@ export function getUseDefineForClassFields(compilerOptions: CompilerOptions): bo
|
||||
return compilerOptions.useDefineForClassFields === undefined ? getEmitScriptTarget(compilerOptions) >= ScriptTarget.ES2022 : compilerOptions.useDefineForClassFields;
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
export function getEmitStandardClassFields(compilerOptions: CompilerOptions) {
|
||||
return compilerOptions.useDefineForClassFields !== false && getEmitScriptTarget(compilerOptions) >= ScriptTarget.ES2022;
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
export function compilerOptionsAffectSemanticDiagnostics(newOptions: CompilerOptions, oldOptions: CompilerOptions): boolean {
|
||||
return optionsHaveChanges(oldOptions, newOptions, semanticDiagnosticsOptionDeclarations);
|
||||
|
||||
+5
-1
@@ -2,9 +2,10 @@ assignParameterPropertyToPropertyDeclarationES2022.ts(2,16): error TS2729: Prope
|
||||
assignParameterPropertyToPropertyDeclarationES2022.ts(3,16): error TS2729: Property 'foo' is used before its initialization.
|
||||
assignParameterPropertyToPropertyDeclarationES2022.ts(6,19): error TS2729: Property 'm3' is used before its initialization.
|
||||
assignParameterPropertyToPropertyDeclarationES2022.ts(12,17): error TS2729: Property 'baz' is used before its initialization.
|
||||
assignParameterPropertyToPropertyDeclarationES2022.ts(13,16): error TS2729: Property 'foo' is used before its initialization.
|
||||
|
||||
|
||||
==== assignParameterPropertyToPropertyDeclarationES2022.ts (4 errors) ====
|
||||
==== assignParameterPropertyToPropertyDeclarationES2022.ts (5 errors) ====
|
||||
class C {
|
||||
qux = this.bar // should error
|
||||
~~~
|
||||
@@ -30,6 +31,9 @@ assignParameterPropertyToPropertyDeclarationES2022.ts(12,17): error TS2729: Prop
|
||||
!!! error TS2729: Property 'baz' is used before its initialization.
|
||||
!!! related TS2728 assignParameterPropertyToPropertyDeclarationES2022.ts:13:5: 'baz' is declared here.
|
||||
baz = this.foo; // should error
|
||||
~~~
|
||||
!!! error TS2729: Property 'foo' is used before its initialization.
|
||||
!!! related TS2728 assignParameterPropertyToPropertyDeclarationES2022.ts:11:17: 'foo' is declared here.
|
||||
quid = this.baz // ok
|
||||
m2() {
|
||||
this.foo // ok
|
||||
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
//// [tests/cases/conformance/classes/propertyMemberDeclarations/initializationOrdering1.ts] ////
|
||||
|
||||
//// [initializationOrdering1.ts]
|
||||
class Helper {
|
||||
create(): boolean {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
export class Broken {
|
||||
constructor(readonly facade: Helper) {
|
||||
console.log(this.bug)
|
||||
}
|
||||
bug = this.facade.create()
|
||||
|
||||
}
|
||||
|
||||
new Broken(new Helper)
|
||||
|
||||
//// [initializationOrdering1.js]
|
||||
class Helper {
|
||||
create() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
export class Broken {
|
||||
constructor(facade) {
|
||||
this.facade = facade;
|
||||
this.bug = this.facade.create();
|
||||
console.log(this.bug);
|
||||
}
|
||||
}
|
||||
new Broken(new Helper);
|
||||
+42
@@ -0,0 +1,42 @@
|
||||
//// [tests/cases/conformance/classes/propertyMemberDeclarations/initializationOrdering1.ts] ////
|
||||
|
||||
=== initializationOrdering1.ts ===
|
||||
class Helper {
|
||||
>Helper : Symbol(Helper, Decl(initializationOrdering1.ts, 0, 0))
|
||||
|
||||
create(): boolean {
|
||||
>create : Symbol(Helper.create, Decl(initializationOrdering1.ts, 0, 14))
|
||||
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
export class Broken {
|
||||
>Broken : Symbol(Broken, Decl(initializationOrdering1.ts, 4, 1))
|
||||
|
||||
constructor(readonly facade: Helper) {
|
||||
>facade : Symbol(Broken.facade, Decl(initializationOrdering1.ts, 7, 16))
|
||||
>Helper : Symbol(Helper, Decl(initializationOrdering1.ts, 0, 0))
|
||||
|
||||
console.log(this.bug)
|
||||
>console.log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --))
|
||||
>console : Symbol(console, Decl(lib.dom.d.ts, --, --))
|
||||
>log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --))
|
||||
>this.bug : Symbol(Broken.bug, Decl(initializationOrdering1.ts, 9, 5))
|
||||
>this : Symbol(Broken, Decl(initializationOrdering1.ts, 4, 1))
|
||||
>bug : Symbol(Broken.bug, Decl(initializationOrdering1.ts, 9, 5))
|
||||
}
|
||||
bug = this.facade.create()
|
||||
>bug : Symbol(Broken.bug, Decl(initializationOrdering1.ts, 9, 5))
|
||||
>this.facade.create : Symbol(Helper.create, Decl(initializationOrdering1.ts, 0, 14))
|
||||
>this.facade : Symbol(Broken.facade, Decl(initializationOrdering1.ts, 7, 16))
|
||||
>this : Symbol(Broken, Decl(initializationOrdering1.ts, 4, 1))
|
||||
>facade : Symbol(Broken.facade, Decl(initializationOrdering1.ts, 7, 16))
|
||||
>create : Symbol(Helper.create, Decl(initializationOrdering1.ts, 0, 14))
|
||||
|
||||
}
|
||||
|
||||
new Broken(new Helper)
|
||||
>Broken : Symbol(Broken, Decl(initializationOrdering1.ts, 4, 1))
|
||||
>Helper : Symbol(Helper, Decl(initializationOrdering1.ts, 0, 0))
|
||||
|
||||
+46
@@ -0,0 +1,46 @@
|
||||
//// [tests/cases/conformance/classes/propertyMemberDeclarations/initializationOrdering1.ts] ////
|
||||
|
||||
=== initializationOrdering1.ts ===
|
||||
class Helper {
|
||||
>Helper : Helper
|
||||
|
||||
create(): boolean {
|
||||
>create : () => boolean
|
||||
|
||||
return true
|
||||
>true : true
|
||||
}
|
||||
}
|
||||
|
||||
export class Broken {
|
||||
>Broken : Broken
|
||||
|
||||
constructor(readonly facade: Helper) {
|
||||
>facade : Helper
|
||||
|
||||
console.log(this.bug)
|
||||
>console.log(this.bug) : void
|
||||
>console.log : (...data: any[]) => void
|
||||
>console : Console
|
||||
>log : (...data: any[]) => void
|
||||
>this.bug : boolean
|
||||
>this : this
|
||||
>bug : boolean
|
||||
}
|
||||
bug = this.facade.create()
|
||||
>bug : boolean
|
||||
>this.facade.create() : boolean
|
||||
>this.facade.create : () => boolean
|
||||
>this.facade : Helper
|
||||
>this : this
|
||||
>facade : Helper
|
||||
>create : () => boolean
|
||||
|
||||
}
|
||||
|
||||
new Broken(new Helper)
|
||||
>new Broken(new Helper) : Broken
|
||||
>Broken : typeof Broken
|
||||
>new Helper : Helper
|
||||
>Helper : typeof Helper
|
||||
|
||||
+43
@@ -0,0 +1,43 @@
|
||||
//// [tests/cases/conformance/classes/propertyMemberDeclarations/initializationOrdering1.ts] ////
|
||||
|
||||
//// [initializationOrdering1.ts]
|
||||
class Helper {
|
||||
create(): boolean {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
export class Broken {
|
||||
constructor(readonly facade: Helper) {
|
||||
console.log(this.bug)
|
||||
}
|
||||
bug = this.facade.create()
|
||||
|
||||
}
|
||||
|
||||
new Broken(new Helper)
|
||||
|
||||
//// [initializationOrdering1.js]
|
||||
class Helper {
|
||||
create() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
export class Broken {
|
||||
constructor(facade) {
|
||||
Object.defineProperty(this, "facade", {
|
||||
enumerable: true,
|
||||
configurable: true,
|
||||
writable: true,
|
||||
value: facade
|
||||
});
|
||||
Object.defineProperty(this, "bug", {
|
||||
enumerable: true,
|
||||
configurable: true,
|
||||
writable: true,
|
||||
value: this.facade.create()
|
||||
});
|
||||
console.log(this.bug);
|
||||
}
|
||||
}
|
||||
new Broken(new Helper);
|
||||
+42
@@ -0,0 +1,42 @@
|
||||
//// [tests/cases/conformance/classes/propertyMemberDeclarations/initializationOrdering1.ts] ////
|
||||
|
||||
=== initializationOrdering1.ts ===
|
||||
class Helper {
|
||||
>Helper : Symbol(Helper, Decl(initializationOrdering1.ts, 0, 0))
|
||||
|
||||
create(): boolean {
|
||||
>create : Symbol(Helper.create, Decl(initializationOrdering1.ts, 0, 14))
|
||||
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
export class Broken {
|
||||
>Broken : Symbol(Broken, Decl(initializationOrdering1.ts, 4, 1))
|
||||
|
||||
constructor(readonly facade: Helper) {
|
||||
>facade : Symbol(Broken.facade, Decl(initializationOrdering1.ts, 7, 16))
|
||||
>Helper : Symbol(Helper, Decl(initializationOrdering1.ts, 0, 0))
|
||||
|
||||
console.log(this.bug)
|
||||
>console.log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --))
|
||||
>console : Symbol(console, Decl(lib.dom.d.ts, --, --))
|
||||
>log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --))
|
||||
>this.bug : Symbol(Broken.bug, Decl(initializationOrdering1.ts, 9, 5))
|
||||
>this : Symbol(Broken, Decl(initializationOrdering1.ts, 4, 1))
|
||||
>bug : Symbol(Broken.bug, Decl(initializationOrdering1.ts, 9, 5))
|
||||
}
|
||||
bug = this.facade.create()
|
||||
>bug : Symbol(Broken.bug, Decl(initializationOrdering1.ts, 9, 5))
|
||||
>this.facade.create : Symbol(Helper.create, Decl(initializationOrdering1.ts, 0, 14))
|
||||
>this.facade : Symbol(Broken.facade, Decl(initializationOrdering1.ts, 7, 16))
|
||||
>this : Symbol(Broken, Decl(initializationOrdering1.ts, 4, 1))
|
||||
>facade : Symbol(Broken.facade, Decl(initializationOrdering1.ts, 7, 16))
|
||||
>create : Symbol(Helper.create, Decl(initializationOrdering1.ts, 0, 14))
|
||||
|
||||
}
|
||||
|
||||
new Broken(new Helper)
|
||||
>Broken : Symbol(Broken, Decl(initializationOrdering1.ts, 4, 1))
|
||||
>Helper : Symbol(Helper, Decl(initializationOrdering1.ts, 0, 0))
|
||||
|
||||
+46
@@ -0,0 +1,46 @@
|
||||
//// [tests/cases/conformance/classes/propertyMemberDeclarations/initializationOrdering1.ts] ////
|
||||
|
||||
=== initializationOrdering1.ts ===
|
||||
class Helper {
|
||||
>Helper : Helper
|
||||
|
||||
create(): boolean {
|
||||
>create : () => boolean
|
||||
|
||||
return true
|
||||
>true : true
|
||||
}
|
||||
}
|
||||
|
||||
export class Broken {
|
||||
>Broken : Broken
|
||||
|
||||
constructor(readonly facade: Helper) {
|
||||
>facade : Helper
|
||||
|
||||
console.log(this.bug)
|
||||
>console.log(this.bug) : void
|
||||
>console.log : (...data: any[]) => void
|
||||
>console : Console
|
||||
>log : (...data: any[]) => void
|
||||
>this.bug : boolean
|
||||
>this : this
|
||||
>bug : boolean
|
||||
}
|
||||
bug = this.facade.create()
|
||||
>bug : boolean
|
||||
>this.facade.create() : boolean
|
||||
>this.facade.create : () => boolean
|
||||
>this.facade : Helper
|
||||
>this : this
|
||||
>facade : Helper
|
||||
>create : () => boolean
|
||||
|
||||
}
|
||||
|
||||
new Broken(new Helper)
|
||||
>new Broken(new Helper) : Broken
|
||||
>Broken : typeof Broken
|
||||
>new Helper : Helper
|
||||
>Helper : typeof Helper
|
||||
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
//// [tests/cases/conformance/classes/propertyMemberDeclarations/initializationOrdering1.ts] ////
|
||||
|
||||
//// [initializationOrdering1.ts]
|
||||
class Helper {
|
||||
create(): boolean {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
export class Broken {
|
||||
constructor(readonly facade: Helper) {
|
||||
console.log(this.bug)
|
||||
}
|
||||
bug = this.facade.create()
|
||||
|
||||
}
|
||||
|
||||
new Broken(new Helper)
|
||||
|
||||
//// [initializationOrdering1.js]
|
||||
class Helper {
|
||||
create() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
export class Broken {
|
||||
constructor(facade) {
|
||||
this.facade = facade;
|
||||
this.bug = this.facade.create();
|
||||
console.log(this.bug);
|
||||
}
|
||||
}
|
||||
new Broken(new Helper);
|
||||
+42
@@ -0,0 +1,42 @@
|
||||
//// [tests/cases/conformance/classes/propertyMemberDeclarations/initializationOrdering1.ts] ////
|
||||
|
||||
=== initializationOrdering1.ts ===
|
||||
class Helper {
|
||||
>Helper : Symbol(Helper, Decl(initializationOrdering1.ts, 0, 0))
|
||||
|
||||
create(): boolean {
|
||||
>create : Symbol(Helper.create, Decl(initializationOrdering1.ts, 0, 14))
|
||||
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
export class Broken {
|
||||
>Broken : Symbol(Broken, Decl(initializationOrdering1.ts, 4, 1))
|
||||
|
||||
constructor(readonly facade: Helper) {
|
||||
>facade : Symbol(Broken.facade, Decl(initializationOrdering1.ts, 7, 16))
|
||||
>Helper : Symbol(Helper, Decl(initializationOrdering1.ts, 0, 0))
|
||||
|
||||
console.log(this.bug)
|
||||
>console.log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --))
|
||||
>console : Symbol(console, Decl(lib.dom.d.ts, --, --))
|
||||
>log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --))
|
||||
>this.bug : Symbol(Broken.bug, Decl(initializationOrdering1.ts, 9, 5))
|
||||
>this : Symbol(Broken, Decl(initializationOrdering1.ts, 4, 1))
|
||||
>bug : Symbol(Broken.bug, Decl(initializationOrdering1.ts, 9, 5))
|
||||
}
|
||||
bug = this.facade.create()
|
||||
>bug : Symbol(Broken.bug, Decl(initializationOrdering1.ts, 9, 5))
|
||||
>this.facade.create : Symbol(Helper.create, Decl(initializationOrdering1.ts, 0, 14))
|
||||
>this.facade : Symbol(Broken.facade, Decl(initializationOrdering1.ts, 7, 16))
|
||||
>this : Symbol(Broken, Decl(initializationOrdering1.ts, 4, 1))
|
||||
>facade : Symbol(Broken.facade, Decl(initializationOrdering1.ts, 7, 16))
|
||||
>create : Symbol(Helper.create, Decl(initializationOrdering1.ts, 0, 14))
|
||||
|
||||
}
|
||||
|
||||
new Broken(new Helper)
|
||||
>Broken : Symbol(Broken, Decl(initializationOrdering1.ts, 4, 1))
|
||||
>Helper : Symbol(Helper, Decl(initializationOrdering1.ts, 0, 0))
|
||||
|
||||
+46
@@ -0,0 +1,46 @@
|
||||
//// [tests/cases/conformance/classes/propertyMemberDeclarations/initializationOrdering1.ts] ////
|
||||
|
||||
=== initializationOrdering1.ts ===
|
||||
class Helper {
|
||||
>Helper : Helper
|
||||
|
||||
create(): boolean {
|
||||
>create : () => boolean
|
||||
|
||||
return true
|
||||
>true : true
|
||||
}
|
||||
}
|
||||
|
||||
export class Broken {
|
||||
>Broken : Broken
|
||||
|
||||
constructor(readonly facade: Helper) {
|
||||
>facade : Helper
|
||||
|
||||
console.log(this.bug)
|
||||
>console.log(this.bug) : void
|
||||
>console.log : (...data: any[]) => void
|
||||
>console : Console
|
||||
>log : (...data: any[]) => void
|
||||
>this.bug : boolean
|
||||
>this : this
|
||||
>bug : boolean
|
||||
}
|
||||
bug = this.facade.create()
|
||||
>bug : boolean
|
||||
>this.facade.create() : boolean
|
||||
>this.facade.create : () => boolean
|
||||
>this.facade : Helper
|
||||
>this : this
|
||||
>facade : Helper
|
||||
>create : () => boolean
|
||||
|
||||
}
|
||||
|
||||
new Broken(new Helper)
|
||||
>new Broken(new Helper) : Broken
|
||||
>Broken : typeof Broken
|
||||
>new Helper : Helper
|
||||
>Helper : typeof Helper
|
||||
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
initializationOrdering1.ts(11,16): error TS2729: Property 'facade' is used before its initialization.
|
||||
|
||||
|
||||
==== initializationOrdering1.ts (1 errors) ====
|
||||
class Helper {
|
||||
create(): boolean {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
export class Broken {
|
||||
constructor(readonly facade: Helper) {
|
||||
console.log(this.bug)
|
||||
}
|
||||
bug = this.facade.create()
|
||||
~~~~~~
|
||||
!!! error TS2729: Property 'facade' is used before its initialization.
|
||||
!!! related TS2728 initializationOrdering1.ts:8:17: 'facade' is declared here.
|
||||
|
||||
}
|
||||
|
||||
new Broken(new Helper)
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
//// [tests/cases/conformance/classes/propertyMemberDeclarations/initializationOrdering1.ts] ////
|
||||
|
||||
//// [initializationOrdering1.ts]
|
||||
class Helper {
|
||||
create(): boolean {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
export class Broken {
|
||||
constructor(readonly facade: Helper) {
|
||||
console.log(this.bug)
|
||||
}
|
||||
bug = this.facade.create()
|
||||
|
||||
}
|
||||
|
||||
new Broken(new Helper)
|
||||
|
||||
//// [initializationOrdering1.js]
|
||||
class Helper {
|
||||
create() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
export class Broken {
|
||||
facade;
|
||||
constructor(facade) {
|
||||
this.facade = facade;
|
||||
console.log(this.bug);
|
||||
}
|
||||
bug = this.facade.create();
|
||||
}
|
||||
new Broken(new Helper);
|
||||
+42
@@ -0,0 +1,42 @@
|
||||
//// [tests/cases/conformance/classes/propertyMemberDeclarations/initializationOrdering1.ts] ////
|
||||
|
||||
=== initializationOrdering1.ts ===
|
||||
class Helper {
|
||||
>Helper : Symbol(Helper, Decl(initializationOrdering1.ts, 0, 0))
|
||||
|
||||
create(): boolean {
|
||||
>create : Symbol(Helper.create, Decl(initializationOrdering1.ts, 0, 14))
|
||||
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
export class Broken {
|
||||
>Broken : Symbol(Broken, Decl(initializationOrdering1.ts, 4, 1))
|
||||
|
||||
constructor(readonly facade: Helper) {
|
||||
>facade : Symbol(Broken.facade, Decl(initializationOrdering1.ts, 7, 16))
|
||||
>Helper : Symbol(Helper, Decl(initializationOrdering1.ts, 0, 0))
|
||||
|
||||
console.log(this.bug)
|
||||
>console.log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --))
|
||||
>console : Symbol(console, Decl(lib.dom.d.ts, --, --))
|
||||
>log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --))
|
||||
>this.bug : Symbol(Broken.bug, Decl(initializationOrdering1.ts, 9, 5))
|
||||
>this : Symbol(Broken, Decl(initializationOrdering1.ts, 4, 1))
|
||||
>bug : Symbol(Broken.bug, Decl(initializationOrdering1.ts, 9, 5))
|
||||
}
|
||||
bug = this.facade.create()
|
||||
>bug : Symbol(Broken.bug, Decl(initializationOrdering1.ts, 9, 5))
|
||||
>this.facade.create : Symbol(Helper.create, Decl(initializationOrdering1.ts, 0, 14))
|
||||
>this.facade : Symbol(Broken.facade, Decl(initializationOrdering1.ts, 7, 16))
|
||||
>this : Symbol(Broken, Decl(initializationOrdering1.ts, 4, 1))
|
||||
>facade : Symbol(Broken.facade, Decl(initializationOrdering1.ts, 7, 16))
|
||||
>create : Symbol(Helper.create, Decl(initializationOrdering1.ts, 0, 14))
|
||||
|
||||
}
|
||||
|
||||
new Broken(new Helper)
|
||||
>Broken : Symbol(Broken, Decl(initializationOrdering1.ts, 4, 1))
|
||||
>Helper : Symbol(Helper, Decl(initializationOrdering1.ts, 0, 0))
|
||||
|
||||
+46
@@ -0,0 +1,46 @@
|
||||
//// [tests/cases/conformance/classes/propertyMemberDeclarations/initializationOrdering1.ts] ////
|
||||
|
||||
=== initializationOrdering1.ts ===
|
||||
class Helper {
|
||||
>Helper : Helper
|
||||
|
||||
create(): boolean {
|
||||
>create : () => boolean
|
||||
|
||||
return true
|
||||
>true : true
|
||||
}
|
||||
}
|
||||
|
||||
export class Broken {
|
||||
>Broken : Broken
|
||||
|
||||
constructor(readonly facade: Helper) {
|
||||
>facade : Helper
|
||||
|
||||
console.log(this.bug)
|
||||
>console.log(this.bug) : void
|
||||
>console.log : (...data: any[]) => void
|
||||
>console : Console
|
||||
>log : (...data: any[]) => void
|
||||
>this.bug : boolean
|
||||
>this : this
|
||||
>bug : boolean
|
||||
}
|
||||
bug = this.facade.create()
|
||||
>bug : boolean
|
||||
>this.facade.create() : boolean
|
||||
>this.facade.create : () => boolean
|
||||
>this.facade : Helper
|
||||
>this : this
|
||||
>facade : Helper
|
||||
>create : () => boolean
|
||||
|
||||
}
|
||||
|
||||
new Broken(new Helper)
|
||||
>new Broken(new Helper) : Broken
|
||||
>Broken : typeof Broken
|
||||
>new Helper : Helper
|
||||
>Helper : typeof Helper
|
||||
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
//// [tests/cases/conformance/classes/propertyMemberDeclarations/initializationOrdering1.ts] ////
|
||||
|
||||
//// [initializationOrdering1.ts]
|
||||
class Helper {
|
||||
create(): boolean {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
export class Broken {
|
||||
constructor(readonly facade: Helper) {
|
||||
console.log(this.bug)
|
||||
}
|
||||
bug = this.facade.create()
|
||||
|
||||
}
|
||||
|
||||
new Broken(new Helper)
|
||||
|
||||
//// [initializationOrdering1.js]
|
||||
class Helper {
|
||||
create() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
export class Broken {
|
||||
constructor(facade) {
|
||||
this.facade = facade;
|
||||
this.bug = this.facade.create();
|
||||
console.log(this.bug);
|
||||
}
|
||||
}
|
||||
new Broken(new Helper);
|
||||
+42
@@ -0,0 +1,42 @@
|
||||
//// [tests/cases/conformance/classes/propertyMemberDeclarations/initializationOrdering1.ts] ////
|
||||
|
||||
=== initializationOrdering1.ts ===
|
||||
class Helper {
|
||||
>Helper : Symbol(Helper, Decl(initializationOrdering1.ts, 0, 0))
|
||||
|
||||
create(): boolean {
|
||||
>create : Symbol(Helper.create, Decl(initializationOrdering1.ts, 0, 14))
|
||||
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
export class Broken {
|
||||
>Broken : Symbol(Broken, Decl(initializationOrdering1.ts, 4, 1))
|
||||
|
||||
constructor(readonly facade: Helper) {
|
||||
>facade : Symbol(Broken.facade, Decl(initializationOrdering1.ts, 7, 16))
|
||||
>Helper : Symbol(Helper, Decl(initializationOrdering1.ts, 0, 0))
|
||||
|
||||
console.log(this.bug)
|
||||
>console.log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --))
|
||||
>console : Symbol(console, Decl(lib.dom.d.ts, --, --))
|
||||
>log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --))
|
||||
>this.bug : Symbol(Broken.bug, Decl(initializationOrdering1.ts, 9, 5))
|
||||
>this : Symbol(Broken, Decl(initializationOrdering1.ts, 4, 1))
|
||||
>bug : Symbol(Broken.bug, Decl(initializationOrdering1.ts, 9, 5))
|
||||
}
|
||||
bug = this.facade.create()
|
||||
>bug : Symbol(Broken.bug, Decl(initializationOrdering1.ts, 9, 5))
|
||||
>this.facade.create : Symbol(Helper.create, Decl(initializationOrdering1.ts, 0, 14))
|
||||
>this.facade : Symbol(Broken.facade, Decl(initializationOrdering1.ts, 7, 16))
|
||||
>this : Symbol(Broken, Decl(initializationOrdering1.ts, 4, 1))
|
||||
>facade : Symbol(Broken.facade, Decl(initializationOrdering1.ts, 7, 16))
|
||||
>create : Symbol(Helper.create, Decl(initializationOrdering1.ts, 0, 14))
|
||||
|
||||
}
|
||||
|
||||
new Broken(new Helper)
|
||||
>Broken : Symbol(Broken, Decl(initializationOrdering1.ts, 4, 1))
|
||||
>Helper : Symbol(Helper, Decl(initializationOrdering1.ts, 0, 0))
|
||||
|
||||
+46
@@ -0,0 +1,46 @@
|
||||
//// [tests/cases/conformance/classes/propertyMemberDeclarations/initializationOrdering1.ts] ////
|
||||
|
||||
=== initializationOrdering1.ts ===
|
||||
class Helper {
|
||||
>Helper : Helper
|
||||
|
||||
create(): boolean {
|
||||
>create : () => boolean
|
||||
|
||||
return true
|
||||
>true : true
|
||||
}
|
||||
}
|
||||
|
||||
export class Broken {
|
||||
>Broken : Broken
|
||||
|
||||
constructor(readonly facade: Helper) {
|
||||
>facade : Helper
|
||||
|
||||
console.log(this.bug)
|
||||
>console.log(this.bug) : void
|
||||
>console.log : (...data: any[]) => void
|
||||
>console : Console
|
||||
>log : (...data: any[]) => void
|
||||
>this.bug : boolean
|
||||
>this : this
|
||||
>bug : boolean
|
||||
}
|
||||
bug = this.facade.create()
|
||||
>bug : boolean
|
||||
>this.facade.create() : boolean
|
||||
>this.facade.create : () => boolean
|
||||
>this.facade : Helper
|
||||
>this : this
|
||||
>facade : Helper
|
||||
>create : () => boolean
|
||||
|
||||
}
|
||||
|
||||
new Broken(new Helper)
|
||||
>new Broken(new Helper) : Broken
|
||||
>Broken : typeof Broken
|
||||
>new Helper : Helper
|
||||
>Helper : typeof Helper
|
||||
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
initializationOrdering1.ts(11,16): error TS2729: Property 'facade' is used before its initialization.
|
||||
|
||||
|
||||
==== initializationOrdering1.ts (1 errors) ====
|
||||
class Helper {
|
||||
create(): boolean {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
export class Broken {
|
||||
constructor(readonly facade: Helper) {
|
||||
console.log(this.bug)
|
||||
}
|
||||
bug = this.facade.create()
|
||||
~~~~~~
|
||||
!!! error TS2729: Property 'facade' is used before its initialization.
|
||||
!!! related TS2728 initializationOrdering1.ts:8:17: 'facade' is declared here.
|
||||
|
||||
}
|
||||
|
||||
new Broken(new Helper)
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
//// [tests/cases/conformance/classes/propertyMemberDeclarations/initializationOrdering1.ts] ////
|
||||
|
||||
//// [initializationOrdering1.ts]
|
||||
class Helper {
|
||||
create(): boolean {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
export class Broken {
|
||||
constructor(readonly facade: Helper) {
|
||||
console.log(this.bug)
|
||||
}
|
||||
bug = this.facade.create()
|
||||
|
||||
}
|
||||
|
||||
new Broken(new Helper)
|
||||
|
||||
//// [initializationOrdering1.js]
|
||||
class Helper {
|
||||
create() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
export class Broken {
|
||||
facade;
|
||||
constructor(facade) {
|
||||
this.facade = facade;
|
||||
console.log(this.bug);
|
||||
}
|
||||
bug = this.facade.create();
|
||||
}
|
||||
new Broken(new Helper);
|
||||
+42
@@ -0,0 +1,42 @@
|
||||
//// [tests/cases/conformance/classes/propertyMemberDeclarations/initializationOrdering1.ts] ////
|
||||
|
||||
=== initializationOrdering1.ts ===
|
||||
class Helper {
|
||||
>Helper : Symbol(Helper, Decl(initializationOrdering1.ts, 0, 0))
|
||||
|
||||
create(): boolean {
|
||||
>create : Symbol(Helper.create, Decl(initializationOrdering1.ts, 0, 14))
|
||||
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
export class Broken {
|
||||
>Broken : Symbol(Broken, Decl(initializationOrdering1.ts, 4, 1))
|
||||
|
||||
constructor(readonly facade: Helper) {
|
||||
>facade : Symbol(Broken.facade, Decl(initializationOrdering1.ts, 7, 16))
|
||||
>Helper : Symbol(Helper, Decl(initializationOrdering1.ts, 0, 0))
|
||||
|
||||
console.log(this.bug)
|
||||
>console.log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --))
|
||||
>console : Symbol(console, Decl(lib.dom.d.ts, --, --))
|
||||
>log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --))
|
||||
>this.bug : Symbol(Broken.bug, Decl(initializationOrdering1.ts, 9, 5))
|
||||
>this : Symbol(Broken, Decl(initializationOrdering1.ts, 4, 1))
|
||||
>bug : Symbol(Broken.bug, Decl(initializationOrdering1.ts, 9, 5))
|
||||
}
|
||||
bug = this.facade.create()
|
||||
>bug : Symbol(Broken.bug, Decl(initializationOrdering1.ts, 9, 5))
|
||||
>this.facade.create : Symbol(Helper.create, Decl(initializationOrdering1.ts, 0, 14))
|
||||
>this.facade : Symbol(Broken.facade, Decl(initializationOrdering1.ts, 7, 16))
|
||||
>this : Symbol(Broken, Decl(initializationOrdering1.ts, 4, 1))
|
||||
>facade : Symbol(Broken.facade, Decl(initializationOrdering1.ts, 7, 16))
|
||||
>create : Symbol(Helper.create, Decl(initializationOrdering1.ts, 0, 14))
|
||||
|
||||
}
|
||||
|
||||
new Broken(new Helper)
|
||||
>Broken : Symbol(Broken, Decl(initializationOrdering1.ts, 4, 1))
|
||||
>Helper : Symbol(Helper, Decl(initializationOrdering1.ts, 0, 0))
|
||||
|
||||
+46
@@ -0,0 +1,46 @@
|
||||
//// [tests/cases/conformance/classes/propertyMemberDeclarations/initializationOrdering1.ts] ////
|
||||
|
||||
=== initializationOrdering1.ts ===
|
||||
class Helper {
|
||||
>Helper : Helper
|
||||
|
||||
create(): boolean {
|
||||
>create : () => boolean
|
||||
|
||||
return true
|
||||
>true : true
|
||||
}
|
||||
}
|
||||
|
||||
export class Broken {
|
||||
>Broken : Broken
|
||||
|
||||
constructor(readonly facade: Helper) {
|
||||
>facade : Helper
|
||||
|
||||
console.log(this.bug)
|
||||
>console.log(this.bug) : void
|
||||
>console.log : (...data: any[]) => void
|
||||
>console : Console
|
||||
>log : (...data: any[]) => void
|
||||
>this.bug : boolean
|
||||
>this : this
|
||||
>bug : boolean
|
||||
}
|
||||
bug = this.facade.create()
|
||||
>bug : boolean
|
||||
>this.facade.create() : boolean
|
||||
>this.facade.create : () => boolean
|
||||
>this.facade : Helper
|
||||
>this : this
|
||||
>facade : Helper
|
||||
>create : () => boolean
|
||||
|
||||
}
|
||||
|
||||
new Broken(new Helper)
|
||||
>new Broken(new Helper) : Broken
|
||||
>Broken : typeof Broken
|
||||
>new Helper : Helper
|
||||
>Helper : typeof Helper
|
||||
|
||||
+1
-7
@@ -1,21 +1,15 @@
|
||||
privateNameBadSuperUseDefineForClassFields.ts(4,3): error TS2376: A 'super' call must be the first statement in the constructor to refer to 'super' or 'this' when a derived class contains initialized properties, parameter properties, or private identifiers.
|
||||
privateNameBadSuperUseDefineForClassFields.ts(5,5): error TS17009: 'super' must be called before accessing 'this' in the constructor of a derived class.
|
||||
|
||||
|
||||
==== privateNameBadSuperUseDefineForClassFields.ts (2 errors) ====
|
||||
==== privateNameBadSuperUseDefineForClassFields.ts (1 errors) ====
|
||||
class B {};
|
||||
class A extends B {
|
||||
#x;
|
||||
constructor() {
|
||||
~~~~~~~~~~~~~~~
|
||||
this;
|
||||
~~~~~~~~~
|
||||
~~~~
|
||||
!!! error TS17009: 'super' must be called before accessing 'this' in the constructor of a derived class.
|
||||
super();
|
||||
~~~~~~~~~~~~
|
||||
}
|
||||
~~~
|
||||
!!! error TS2376: A 'super' call must be the first statement in the constructor to refer to 'super' or 'this' when a derived class contains initialized properties, parameter properties, or private identifiers.
|
||||
}
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
// @target: esnext, es2021, es2022
|
||||
// @useDefineForClassFields: true, false
|
||||
|
||||
class Helper {
|
||||
create(): boolean {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
export class Broken {
|
||||
constructor(readonly facade: Helper) {
|
||||
console.log(this.bug)
|
||||
}
|
||||
bug = this.facade.create()
|
||||
|
||||
}
|
||||
|
||||
new Broken(new Helper)
|
||||
Reference in New Issue
Block a user