Added error for class properties used within their own declaration (#29395)
* Added error for class properties used within their own declaration Fixes #5987. Usages of a class property in a preceding property already gave an error, but the following doesn't yet: ```ts class Test { x: number = this.x; } ``` As with other use-before-declare checking, IIFEs are not treated as invalid uses. * Accepted 'witness' baselines; removed unnecessary !== * Addressed quick feedback items * Accepted odd new baseline * Fixed post-merge introduced lint errors * Updated baselines again
This commit is contained in:
commit
0b3b4ea127
|
@ -1130,6 +1130,10 @@ namespace ts {
|
|||
// still might be illegal if the usage is within a computed property name in the class (eg class A { static p = "a"; [A.p]() {} })
|
||||
return !findAncestor(usage, n => isComputedPropertyName(n) && n.parent.parent === declaration);
|
||||
}
|
||||
else if (isPropertyDeclaration(declaration)) {
|
||||
// still might be illegal if a self-referencing property initializer (eg private x = this.x)
|
||||
return !isPropertyImmediatelyReferencedWithinDeclaration(declaration, usage);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -1204,6 +1208,40 @@ namespace ts {
|
|||
return false;
|
||||
});
|
||||
}
|
||||
|
||||
function isPropertyImmediatelyReferencedWithinDeclaration(declaration: PropertyDeclaration, usage: Node) {
|
||||
// always legal if usage is after declaration
|
||||
if (usage.end > declaration.end) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// still might be legal if usage is deferred (e.g. x: any = () => this.x)
|
||||
// otherwise illegal if immediately referenced within the declaration (e.g. x: any = this.x)
|
||||
const ancestorChangingReferenceScope = findAncestor(usage, (node: Node) => {
|
||||
if (node === declaration) {
|
||||
return "quit";
|
||||
}
|
||||
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.ArrowFunction:
|
||||
case SyntaxKind.PropertyDeclaration:
|
||||
return true;
|
||||
case SyntaxKind.Block:
|
||||
switch (node.parent.kind) {
|
||||
case SyntaxKind.GetAccessor:
|
||||
case SyntaxKind.MethodDeclaration:
|
||||
case SyntaxKind.SetAccessor:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
return ancestorChangingReferenceScope === undefined;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -0,0 +1,66 @@
|
|||
tests/cases/compiler/classUsedBeforeInitializedVariables.ts(4,15): error TS2729: Property 'p4' is used before its initialization.
|
||||
tests/cases/compiler/classUsedBeforeInitializedVariables.ts(7,34): error TS2729: Property 'directlyAssigned' is used before its initialization.
|
||||
tests/cases/compiler/classUsedBeforeInitializedVariables.ts(16,15): error TS2729: Property 'withinObjectLiteral' is used before its initialization.
|
||||
tests/cases/compiler/classUsedBeforeInitializedVariables.ts(20,19): error TS2729: Property 'withinObjectLiteralGetterName' is used before its initialization.
|
||||
tests/cases/compiler/classUsedBeforeInitializedVariables.ts(26,19): error TS2729: Property 'withinObjectLiteralSetterName' is used before its initialization.
|
||||
tests/cases/compiler/classUsedBeforeInitializedVariables.ts(29,64): error TS2729: Property 'withinClassDeclarationExtension' is used before its initialization.
|
||||
|
||||
|
||||
==== tests/cases/compiler/classUsedBeforeInitializedVariables.ts (6 errors) ====
|
||||
class Test {
|
||||
p1 = 0;
|
||||
p2 = this.p1;
|
||||
p3 = this.p4;
|
||||
~~
|
||||
!!! error TS2729: Property 'p4' is used before its initialization.
|
||||
!!! related TS2728 tests/cases/compiler/classUsedBeforeInitializedVariables.ts:5:5: 'p4' is declared here.
|
||||
p4 = 0;
|
||||
|
||||
directlyAssigned: any = this.directlyAssigned;
|
||||
~~~~~~~~~~~~~~~~
|
||||
!!! error TS2729: Property 'directlyAssigned' is used before its initialization.
|
||||
!!! related TS2728 tests/cases/compiler/classUsedBeforeInitializedVariables.ts:7:5: 'directlyAssigned' is declared here.
|
||||
|
||||
withinArrowFunction: any = () => this.withinArrowFunction;
|
||||
|
||||
withinFunction: any = function () {
|
||||
return this.withinFunction;
|
||||
};
|
||||
|
||||
withinObjectLiteral: any = {
|
||||
[this.withinObjectLiteral]: true,
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
!!! error TS2729: Property 'withinObjectLiteral' is used before its initialization.
|
||||
!!! related TS2728 tests/cases/compiler/classUsedBeforeInitializedVariables.ts:15:5: 'withinObjectLiteral' is declared here.
|
||||
};
|
||||
|
||||
withinObjectLiteralGetterName: any = {
|
||||
get [this.withinObjectLiteralGetterName]() {
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
!!! error TS2729: Property 'withinObjectLiteralGetterName' is used before its initialization.
|
||||
!!! related TS2728 tests/cases/compiler/classUsedBeforeInitializedVariables.ts:19:5: 'withinObjectLiteralGetterName' is declared here.
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
withinObjectLiteralSetterName: any = {
|
||||
set [this.withinObjectLiteralSetterName](_: any) {}
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
!!! error TS2729: Property 'withinObjectLiteralSetterName' is used before its initialization.
|
||||
!!! related TS2728 tests/cases/compiler/classUsedBeforeInitializedVariables.ts:25:5: 'withinObjectLiteralSetterName' is declared here.
|
||||
};
|
||||
|
||||
withinClassDeclarationExtension: any = (class extends this.withinClassDeclarationExtension { });
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
!!! error TS2729: Property 'withinClassDeclarationExtension' is used before its initialization.
|
||||
!!! related TS2728 tests/cases/compiler/classUsedBeforeInitializedVariables.ts:29:5: 'withinClassDeclarationExtension' is declared here.
|
||||
|
||||
// These error cases are ignored (not checked by control flow analysis)
|
||||
|
||||
assignedByArrowFunction: any = (() => this.assignedByFunction)();
|
||||
|
||||
assignedByFunction: any = (function () {
|
||||
return this.assignedByFunction;
|
||||
})();
|
||||
}
|
||||
|
102
tests/baselines/reference/classUsedBeforeInitializedVariables.js
Normal file
102
tests/baselines/reference/classUsedBeforeInitializedVariables.js
Normal file
|
@ -0,0 +1,102 @@
|
|||
//// [classUsedBeforeInitializedVariables.ts]
|
||||
class Test {
|
||||
p1 = 0;
|
||||
p2 = this.p1;
|
||||
p3 = this.p4;
|
||||
p4 = 0;
|
||||
|
||||
directlyAssigned: any = this.directlyAssigned;
|
||||
|
||||
withinArrowFunction: any = () => this.withinArrowFunction;
|
||||
|
||||
withinFunction: any = function () {
|
||||
return this.withinFunction;
|
||||
};
|
||||
|
||||
withinObjectLiteral: any = {
|
||||
[this.withinObjectLiteral]: true,
|
||||
};
|
||||
|
||||
withinObjectLiteralGetterName: any = {
|
||||
get [this.withinObjectLiteralGetterName]() {
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
withinObjectLiteralSetterName: any = {
|
||||
set [this.withinObjectLiteralSetterName](_: any) {}
|
||||
};
|
||||
|
||||
withinClassDeclarationExtension: any = (class extends this.withinClassDeclarationExtension { });
|
||||
|
||||
// These error cases are ignored (not checked by control flow analysis)
|
||||
|
||||
assignedByArrowFunction: any = (() => this.assignedByFunction)();
|
||||
|
||||
assignedByFunction: any = (function () {
|
||||
return this.assignedByFunction;
|
||||
})();
|
||||
}
|
||||
|
||||
|
||||
//// [classUsedBeforeInitializedVariables.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 Test = /** @class */ (function () {
|
||||
function Test() {
|
||||
var _a, _b, _c;
|
||||
var _this = this;
|
||||
this.p1 = 0;
|
||||
this.p2 = this.p1;
|
||||
this.p3 = this.p4;
|
||||
this.p4 = 0;
|
||||
this.directlyAssigned = this.directlyAssigned;
|
||||
this.withinArrowFunction = function () { return _this.withinArrowFunction; };
|
||||
this.withinFunction = function () {
|
||||
return this.withinFunction;
|
||||
};
|
||||
this.withinObjectLiteral = (_a = {},
|
||||
_a[this.withinObjectLiteral] = true,
|
||||
_a);
|
||||
this.withinObjectLiteralGetterName = (_b = {},
|
||||
Object.defineProperty(_b, this.withinObjectLiteralGetterName, {
|
||||
get: function () {
|
||||
return true;
|
||||
},
|
||||
enumerable: true,
|
||||
configurable: true
|
||||
}),
|
||||
_b);
|
||||
this.withinObjectLiteralSetterName = (_c = {},
|
||||
Object.defineProperty(_c, this.withinObjectLiteralSetterName, {
|
||||
set: function (_) { },
|
||||
enumerable: true,
|
||||
configurable: true
|
||||
}),
|
||||
_c);
|
||||
this.withinClassDeclarationExtension = (/** @class */ (function (_super) {
|
||||
__extends(class_1, _super);
|
||||
function class_1() {
|
||||
return _super !== null && _super.apply(this, arguments) || this;
|
||||
}
|
||||
return class_1;
|
||||
}(this.withinClassDeclarationExtension)));
|
||||
// These error cases are ignored (not checked by control flow analysis)
|
||||
this.assignedByArrowFunction = (function () { return _this.assignedByFunction; })();
|
||||
this.assignedByFunction = (function () {
|
||||
return this.assignedByFunction;
|
||||
})();
|
||||
}
|
||||
return Test;
|
||||
}());
|
|
@ -0,0 +1,97 @@
|
|||
=== tests/cases/compiler/classUsedBeforeInitializedVariables.ts ===
|
||||
class Test {
|
||||
>Test : Symbol(Test, Decl(classUsedBeforeInitializedVariables.ts, 0, 0))
|
||||
|
||||
p1 = 0;
|
||||
>p1 : Symbol(Test.p1, Decl(classUsedBeforeInitializedVariables.ts, 0, 12))
|
||||
|
||||
p2 = this.p1;
|
||||
>p2 : Symbol(Test.p2, Decl(classUsedBeforeInitializedVariables.ts, 1, 11))
|
||||
>this.p1 : Symbol(Test.p1, Decl(classUsedBeforeInitializedVariables.ts, 0, 12))
|
||||
>this : Symbol(Test, Decl(classUsedBeforeInitializedVariables.ts, 0, 0))
|
||||
>p1 : Symbol(Test.p1, Decl(classUsedBeforeInitializedVariables.ts, 0, 12))
|
||||
|
||||
p3 = this.p4;
|
||||
>p3 : Symbol(Test.p3, Decl(classUsedBeforeInitializedVariables.ts, 2, 17))
|
||||
>this.p4 : Symbol(Test.p4, Decl(classUsedBeforeInitializedVariables.ts, 3, 17))
|
||||
>this : Symbol(Test, Decl(classUsedBeforeInitializedVariables.ts, 0, 0))
|
||||
>p4 : Symbol(Test.p4, Decl(classUsedBeforeInitializedVariables.ts, 3, 17))
|
||||
|
||||
p4 = 0;
|
||||
>p4 : Symbol(Test.p4, Decl(classUsedBeforeInitializedVariables.ts, 3, 17))
|
||||
|
||||
directlyAssigned: any = this.directlyAssigned;
|
||||
>directlyAssigned : Symbol(Test.directlyAssigned, Decl(classUsedBeforeInitializedVariables.ts, 4, 11))
|
||||
>this.directlyAssigned : Symbol(Test.directlyAssigned, Decl(classUsedBeforeInitializedVariables.ts, 4, 11))
|
||||
>this : Symbol(Test, Decl(classUsedBeforeInitializedVariables.ts, 0, 0))
|
||||
>directlyAssigned : Symbol(Test.directlyAssigned, Decl(classUsedBeforeInitializedVariables.ts, 4, 11))
|
||||
|
||||
withinArrowFunction: any = () => this.withinArrowFunction;
|
||||
>withinArrowFunction : Symbol(Test.withinArrowFunction, Decl(classUsedBeforeInitializedVariables.ts, 6, 50))
|
||||
>this.withinArrowFunction : Symbol(Test.withinArrowFunction, Decl(classUsedBeforeInitializedVariables.ts, 6, 50))
|
||||
>this : Symbol(Test, Decl(classUsedBeforeInitializedVariables.ts, 0, 0))
|
||||
>withinArrowFunction : Symbol(Test.withinArrowFunction, Decl(classUsedBeforeInitializedVariables.ts, 6, 50))
|
||||
|
||||
withinFunction: any = function () {
|
||||
>withinFunction : Symbol(Test.withinFunction, Decl(classUsedBeforeInitializedVariables.ts, 8, 62))
|
||||
|
||||
return this.withinFunction;
|
||||
};
|
||||
|
||||
withinObjectLiteral: any = {
|
||||
>withinObjectLiteral : Symbol(Test.withinObjectLiteral, Decl(classUsedBeforeInitializedVariables.ts, 12, 6))
|
||||
|
||||
[this.withinObjectLiteral]: true,
|
||||
>[this.withinObjectLiteral] : Symbol([this.withinObjectLiteral], Decl(classUsedBeforeInitializedVariables.ts, 14, 32))
|
||||
>this.withinObjectLiteral : Symbol(Test.withinObjectLiteral, Decl(classUsedBeforeInitializedVariables.ts, 12, 6))
|
||||
>this : Symbol(Test, Decl(classUsedBeforeInitializedVariables.ts, 0, 0))
|
||||
>withinObjectLiteral : Symbol(Test.withinObjectLiteral, Decl(classUsedBeforeInitializedVariables.ts, 12, 6))
|
||||
|
||||
};
|
||||
|
||||
withinObjectLiteralGetterName: any = {
|
||||
>withinObjectLiteralGetterName : Symbol(Test.withinObjectLiteralGetterName, Decl(classUsedBeforeInitializedVariables.ts, 16, 6))
|
||||
|
||||
get [this.withinObjectLiteralGetterName]() {
|
||||
>[this.withinObjectLiteralGetterName] : Symbol([this.withinObjectLiteralGetterName], Decl(classUsedBeforeInitializedVariables.ts, 18, 42))
|
||||
>this.withinObjectLiteralGetterName : Symbol(Test.withinObjectLiteralGetterName, Decl(classUsedBeforeInitializedVariables.ts, 16, 6))
|
||||
>this : Symbol(Test, Decl(classUsedBeforeInitializedVariables.ts, 0, 0))
|
||||
>withinObjectLiteralGetterName : Symbol(Test.withinObjectLiteralGetterName, Decl(classUsedBeforeInitializedVariables.ts, 16, 6))
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
withinObjectLiteralSetterName: any = {
|
||||
>withinObjectLiteralSetterName : Symbol(Test.withinObjectLiteralSetterName, Decl(classUsedBeforeInitializedVariables.ts, 22, 6))
|
||||
|
||||
set [this.withinObjectLiteralSetterName](_: any) {}
|
||||
>[this.withinObjectLiteralSetterName] : Symbol([this.withinObjectLiteralSetterName], Decl(classUsedBeforeInitializedVariables.ts, 24, 42))
|
||||
>this.withinObjectLiteralSetterName : Symbol(Test.withinObjectLiteralSetterName, Decl(classUsedBeforeInitializedVariables.ts, 22, 6))
|
||||
>this : Symbol(Test, Decl(classUsedBeforeInitializedVariables.ts, 0, 0))
|
||||
>withinObjectLiteralSetterName : Symbol(Test.withinObjectLiteralSetterName, Decl(classUsedBeforeInitializedVariables.ts, 22, 6))
|
||||
>_ : Symbol(_, Decl(classUsedBeforeInitializedVariables.ts, 25, 49))
|
||||
|
||||
};
|
||||
|
||||
withinClassDeclarationExtension: any = (class extends this.withinClassDeclarationExtension { });
|
||||
>withinClassDeclarationExtension : Symbol(Test.withinClassDeclarationExtension, Decl(classUsedBeforeInitializedVariables.ts, 26, 6))
|
||||
>this.withinClassDeclarationExtension : Symbol(Test.withinClassDeclarationExtension, Decl(classUsedBeforeInitializedVariables.ts, 26, 6))
|
||||
>this : Symbol(Test, Decl(classUsedBeforeInitializedVariables.ts, 0, 0))
|
||||
>withinClassDeclarationExtension : Symbol(Test.withinClassDeclarationExtension, Decl(classUsedBeforeInitializedVariables.ts, 26, 6))
|
||||
|
||||
// These error cases are ignored (not checked by control flow analysis)
|
||||
|
||||
assignedByArrowFunction: any = (() => this.assignedByFunction)();
|
||||
>assignedByArrowFunction : Symbol(Test.assignedByArrowFunction, Decl(classUsedBeforeInitializedVariables.ts, 28, 100))
|
||||
>this.assignedByFunction : Symbol(Test.assignedByFunction, Decl(classUsedBeforeInitializedVariables.ts, 32, 69))
|
||||
>this : Symbol(Test, Decl(classUsedBeforeInitializedVariables.ts, 0, 0))
|
||||
>assignedByFunction : Symbol(Test.assignedByFunction, Decl(classUsedBeforeInitializedVariables.ts, 32, 69))
|
||||
|
||||
assignedByFunction: any = (function () {
|
||||
>assignedByFunction : Symbol(Test.assignedByFunction, Decl(classUsedBeforeInitializedVariables.ts, 32, 69))
|
||||
|
||||
return this.assignedByFunction;
|
||||
})();
|
||||
}
|
||||
|
|
@ -0,0 +1,122 @@
|
|||
=== tests/cases/compiler/classUsedBeforeInitializedVariables.ts ===
|
||||
class Test {
|
||||
>Test : Test
|
||||
|
||||
p1 = 0;
|
||||
>p1 : number
|
||||
>0 : 0
|
||||
|
||||
p2 = this.p1;
|
||||
>p2 : number
|
||||
>this.p1 : number
|
||||
>this : this
|
||||
>p1 : number
|
||||
|
||||
p3 = this.p4;
|
||||
>p3 : number
|
||||
>this.p4 : number
|
||||
>this : this
|
||||
>p4 : number
|
||||
|
||||
p4 = 0;
|
||||
>p4 : number
|
||||
>0 : 0
|
||||
|
||||
directlyAssigned: any = this.directlyAssigned;
|
||||
>directlyAssigned : any
|
||||
>this.directlyAssigned : any
|
||||
>this : this
|
||||
>directlyAssigned : any
|
||||
|
||||
withinArrowFunction: any = () => this.withinArrowFunction;
|
||||
>withinArrowFunction : any
|
||||
>() => this.withinArrowFunction : () => any
|
||||
>this.withinArrowFunction : any
|
||||
>this : this
|
||||
>withinArrowFunction : any
|
||||
|
||||
withinFunction: any = function () {
|
||||
>withinFunction : any
|
||||
>function () { return this.withinFunction; } : () => any
|
||||
|
||||
return this.withinFunction;
|
||||
>this.withinFunction : any
|
||||
>this : any
|
||||
>withinFunction : any
|
||||
|
||||
};
|
||||
|
||||
withinObjectLiteral: any = {
|
||||
>withinObjectLiteral : any
|
||||
>{ [this.withinObjectLiteral]: true, } : { [x: number]: boolean; }
|
||||
|
||||
[this.withinObjectLiteral]: true,
|
||||
>[this.withinObjectLiteral] : boolean
|
||||
>this.withinObjectLiteral : any
|
||||
>this : this
|
||||
>withinObjectLiteral : any
|
||||
>true : true
|
||||
|
||||
};
|
||||
|
||||
withinObjectLiteralGetterName: any = {
|
||||
>withinObjectLiteralGetterName : any
|
||||
>{ get [this.withinObjectLiteralGetterName]() { return true; } } : { [x: number]: boolean; }
|
||||
|
||||
get [this.withinObjectLiteralGetterName]() {
|
||||
>[this.withinObjectLiteralGetterName] : boolean
|
||||
>this.withinObjectLiteralGetterName : any
|
||||
>this : this
|
||||
>withinObjectLiteralGetterName : any
|
||||
|
||||
return true;
|
||||
>true : true
|
||||
}
|
||||
};
|
||||
|
||||
withinObjectLiteralSetterName: any = {
|
||||
>withinObjectLiteralSetterName : any
|
||||
>{ set [this.withinObjectLiteralSetterName](_: any) {} } : { [x: number]: any; }
|
||||
|
||||
set [this.withinObjectLiteralSetterName](_: any) {}
|
||||
>[this.withinObjectLiteralSetterName] : any
|
||||
>this.withinObjectLiteralSetterName : any
|
||||
>this : this
|
||||
>withinObjectLiteralSetterName : any
|
||||
>_ : any
|
||||
|
||||
};
|
||||
|
||||
withinClassDeclarationExtension: any = (class extends this.withinClassDeclarationExtension { });
|
||||
>withinClassDeclarationExtension : any
|
||||
>(class extends this.withinClassDeclarationExtension { }) : typeof (Anonymous class)
|
||||
>class extends this.withinClassDeclarationExtension { } : typeof (Anonymous class)
|
||||
>this.withinClassDeclarationExtension : any
|
||||
>this : this
|
||||
>withinClassDeclarationExtension : any
|
||||
|
||||
// These error cases are ignored (not checked by control flow analysis)
|
||||
|
||||
assignedByArrowFunction: any = (() => this.assignedByFunction)();
|
||||
>assignedByArrowFunction : any
|
||||
>(() => this.assignedByFunction)() : any
|
||||
>(() => this.assignedByFunction) : () => any
|
||||
>() => this.assignedByFunction : () => any
|
||||
>this.assignedByFunction : any
|
||||
>this : this
|
||||
>assignedByFunction : any
|
||||
|
||||
assignedByFunction: any = (function () {
|
||||
>assignedByFunction : any
|
||||
>(function () { return this.assignedByFunction; })() : any
|
||||
>(function () { return this.assignedByFunction; }) : () => any
|
||||
>function () { return this.assignedByFunction; } : () => any
|
||||
|
||||
return this.assignedByFunction;
|
||||
>this.assignedByFunction : any
|
||||
>this : any
|
||||
>assignedByFunction : any
|
||||
|
||||
})();
|
||||
}
|
||||
|
|
@ -1,4 +1,5 @@
|
|||
tests/cases/conformance/types/witness/witness.ts(4,21): error TS2372: Parameter 'pInit' cannot be referenced in its initializer.
|
||||
tests/cases/conformance/types/witness/witness.ts(8,14): error TS2729: Property 'x' is used before its initialization.
|
||||
tests/cases/conformance/types/witness/witness.ts(28,12): error TS2695: Left side of comma operator is unused and has no side effects.
|
||||
tests/cases/conformance/types/witness/witness.ts(29,5): error TS2403: Subsequent variable declarations must have the same type. Variable 'co1' must be of type 'any', but here has type 'number'.
|
||||
tests/cases/conformance/types/witness/witness.ts(30,12): error TS2695: Left side of comma operator is unused and has no side effects.
|
||||
|
@ -12,9 +13,11 @@ tests/cases/conformance/types/witness/witness.ts(39,5): error TS2403: Subsequent
|
|||
tests/cases/conformance/types/witness/witness.ts(43,5): error TS2403: Subsequent variable declarations must have the same type. Variable 'cnd1' must be of type 'any', but here has type 'number'.
|
||||
tests/cases/conformance/types/witness/witness.ts(57,5): error TS2403: Subsequent variable declarations must have the same type. Variable 'and1' must be of type 'any', but here has type 'string'.
|
||||
tests/cases/conformance/types/witness/witness.ts(110,5): error TS2403: Subsequent variable declarations must have the same type. Variable 'propAcc1' must be of type 'any', but here has type '{ m: any; }'.
|
||||
tests/cases/conformance/types/witness/witness.ts(121,14): error TS2729: Property 'n' is used before its initialization.
|
||||
tests/cases/conformance/types/witness/witness.ts(128,19): error TS2729: Property 'q' is used before its initialization.
|
||||
|
||||
|
||||
==== tests/cases/conformance/types/witness/witness.ts (14 errors) ====
|
||||
==== tests/cases/conformance/types/witness/witness.ts (17 errors) ====
|
||||
// Initializers
|
||||
var varInit = varInit; // any
|
||||
var pInit: any;
|
||||
|
@ -25,6 +28,9 @@ tests/cases/conformance/types/witness/witness.ts(110,5): error TS2403: Subsequen
|
|||
}
|
||||
class InitClass {
|
||||
x = this.x;
|
||||
~
|
||||
!!! error TS2729: Property 'x' is used before its initialization.
|
||||
!!! related TS2728 tests/cases/conformance/types/witness/witness.ts:8:5: 'x' is declared here.
|
||||
fn() {
|
||||
var y = this.x;
|
||||
var y: any;
|
||||
|
@ -164,6 +170,9 @@ tests/cases/conformance/types/witness/witness.ts(110,5): error TS2403: Subsequen
|
|||
// Property access of class instance type
|
||||
class C2 {
|
||||
n = this.n; // n: any
|
||||
~
|
||||
!!! error TS2729: Property 'n' is used before its initialization.
|
||||
!!! related TS2728 tests/cases/conformance/types/witness/witness.ts:121:5: 'n' is declared here.
|
||||
}
|
||||
var c2inst = new C2().n;
|
||||
var c2inst: any;
|
||||
|
@ -171,6 +180,9 @@ tests/cases/conformance/types/witness/witness.ts(110,5): error TS2403: Subsequen
|
|||
// Constructor function property access
|
||||
class C3 {
|
||||
static q = C3.q;
|
||||
~
|
||||
!!! error TS2729: Property 'q' is used before its initialization.
|
||||
!!! related TS2728 tests/cases/conformance/types/witness/witness.ts:128:12: 'q' is declared here.
|
||||
}
|
||||
var qq = C3.q;
|
||||
var qq: any;
|
||||
|
|
40
tests/cases/compiler/classUsedBeforeInitializedVariables.ts
Normal file
40
tests/cases/compiler/classUsedBeforeInitializedVariables.ts
Normal file
|
@ -0,0 +1,40 @@
|
|||
// @target: es5
|
||||
|
||||
class Test {
|
||||
p1 = 0;
|
||||
p2 = this.p1;
|
||||
p3 = this.p4;
|
||||
p4 = 0;
|
||||
|
||||
directlyAssigned: any = this.directlyAssigned;
|
||||
|
||||
withinArrowFunction: any = () => this.withinArrowFunction;
|
||||
|
||||
withinFunction: any = function () {
|
||||
return this.withinFunction;
|
||||
};
|
||||
|
||||
withinObjectLiteral: any = {
|
||||
[this.withinObjectLiteral]: true,
|
||||
};
|
||||
|
||||
withinObjectLiteralGetterName: any = {
|
||||
get [this.withinObjectLiteralGetterName]() {
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
withinObjectLiteralSetterName: any = {
|
||||
set [this.withinObjectLiteralSetterName](_: any) {}
|
||||
};
|
||||
|
||||
withinClassDeclarationExtension: any = (class extends this.withinClassDeclarationExtension { });
|
||||
|
||||
// These error cases are ignored (not checked by control flow analysis)
|
||||
|
||||
assignedByArrowFunction: any = (() => this.assignedByFunction)();
|
||||
|
||||
assignedByFunction: any = (function () {
|
||||
return this.assignedByFunction;
|
||||
})();
|
||||
}
|
Loading…
Reference in a new issue