Disabled 'used before initialization' error for optional properties (#43100)
* Disabled 'used before initialization' error for optional properties * Expanded tests to include code snippet from issue
This commit is contained in:
parent
f9b35cd302
commit
38da7c600c
|
@ -11936,6 +11936,10 @@ namespace ts {
|
|||
return false;
|
||||
}
|
||||
|
||||
function isOptionalPropertyDeclaration(node: Declaration) {
|
||||
return isPropertyDeclaration(node) && node.questionToken;
|
||||
}
|
||||
|
||||
function isOptionalJSDocPropertyLikeTag(node: Node): node is JSDocPropertyLikeTag {
|
||||
if (!isJSDocPropertyLikeTag(node)) {
|
||||
return false;
|
||||
|
@ -27115,6 +27119,7 @@ namespace ts {
|
|||
let diagnosticMessage;
|
||||
const declarationName = idText(right);
|
||||
if (isInPropertyInitializer(node)
|
||||
&& !isOptionalPropertyDeclaration(valueDeclaration)
|
||||
&& !(isAccessExpression(node) && isAccessExpression(node.expression))
|
||||
&& !isBlockScopedNameDeclaredBeforeUse(valueDeclaration, right)
|
||||
&& (compilerOptions.useDefineForClassFields || !isPropertyDeclaredInAncestorClass(prop))) {
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
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(13,34): error TS2729: Property 'directlyAssigned' is used before its initialization.
|
||||
tests/cases/compiler/classUsedBeforeInitializedVariables.ts(22,15): error TS2729: Property 'withinObjectLiteral' is used before its initialization.
|
||||
tests/cases/compiler/classUsedBeforeInitializedVariables.ts(26,19): error TS2729: Property 'withinObjectLiteralGetterName' is used before its initialization.
|
||||
tests/cases/compiler/classUsedBeforeInitializedVariables.ts(32,19): error TS2729: Property 'withinObjectLiteralSetterName' is used before its initialization.
|
||||
tests/cases/compiler/classUsedBeforeInitializedVariables.ts(35,64): error TS2729: Property 'withinClassDeclarationExtension' is used before its initialization.
|
||||
|
||||
|
||||
==== tests/cases/compiler/classUsedBeforeInitializedVariables.ts (6 errors) ====
|
||||
|
@ -15,11 +15,17 @@ tests/cases/compiler/classUsedBeforeInitializedVariables.ts(29,64): error TS2729
|
|||
!!! error TS2729: Property 'p4' is used before its initialization.
|
||||
!!! related TS2728 tests/cases/compiler/classUsedBeforeInitializedVariables.ts:5:5: 'p4' is declared here.
|
||||
p4 = 0;
|
||||
p5?: number;
|
||||
|
||||
p6?: string;
|
||||
p7 = {
|
||||
hello: (this.p6 = "string"),
|
||||
};
|
||||
|
||||
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.
|
||||
!!! related TS2728 tests/cases/compiler/classUsedBeforeInitializedVariables.ts:13:5: 'directlyAssigned' is declared here.
|
||||
|
||||
withinArrowFunction: any = () => this.withinArrowFunction;
|
||||
|
||||
|
@ -31,14 +37,14 @@ tests/cases/compiler/classUsedBeforeInitializedVariables.ts(29,64): error TS2729
|
|||
[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.
|
||||
!!! related TS2728 tests/cases/compiler/classUsedBeforeInitializedVariables.ts:21: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.
|
||||
!!! related TS2728 tests/cases/compiler/classUsedBeforeInitializedVariables.ts:25:5: 'withinObjectLiteralGetterName' is declared here.
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
@ -47,13 +53,15 @@ tests/cases/compiler/classUsedBeforeInitializedVariables.ts(29,64): error TS2729
|
|||
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.
|
||||
!!! related TS2728 tests/cases/compiler/classUsedBeforeInitializedVariables.ts:31: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.
|
||||
!!! related TS2728 tests/cases/compiler/classUsedBeforeInitializedVariables.ts:35:5: 'withinClassDeclarationExtension' is declared here.
|
||||
|
||||
fromOptional = this.p5;
|
||||
|
||||
// These error cases are ignored (not checked by control flow analysis)
|
||||
|
||||
|
|
|
@ -4,6 +4,12 @@ class Test {
|
|||
p2 = this.p1;
|
||||
p3 = this.p4;
|
||||
p4 = 0;
|
||||
p5?: number;
|
||||
|
||||
p6?: string;
|
||||
p7 = {
|
||||
hello: (this.p6 = "string"),
|
||||
};
|
||||
|
||||
directlyAssigned: any = this.directlyAssigned;
|
||||
|
||||
|
@ -29,6 +35,8 @@ class Test {
|
|||
|
||||
withinClassDeclarationExtension: any = (class extends this.withinClassDeclarationExtension { });
|
||||
|
||||
fromOptional = this.p5;
|
||||
|
||||
// These error cases are ignored (not checked by control flow analysis)
|
||||
|
||||
assignedByArrowFunction: any = (() => this.assignedByFunction)();
|
||||
|
@ -63,6 +71,9 @@ var Test = /** @class */ (function () {
|
|||
this.p2 = this.p1;
|
||||
this.p3 = this.p4;
|
||||
this.p4 = 0;
|
||||
this.p7 = {
|
||||
hello: (this.p6 = "string"),
|
||||
};
|
||||
this.directlyAssigned = this.directlyAssigned;
|
||||
this.withinArrowFunction = function () { return _this.withinArrowFunction; };
|
||||
this.withinFunction = function () {
|
||||
|
@ -94,6 +105,7 @@ var Test = /** @class */ (function () {
|
|||
}
|
||||
return class_1;
|
||||
}(this.withinClassDeclarationExtension)));
|
||||
this.fromOptional = this.p5;
|
||||
// These error cases are ignored (not checked by control flow analysis)
|
||||
this.assignedByArrowFunction = (function () { return _this.assignedByFunction; })();
|
||||
this.assignedByFunction = (function () {
|
||||
|
|
|
@ -20,76 +20,99 @@ class Test {
|
|||
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))
|
||||
p5?: number;
|
||||
>p5 : Symbol(Test.p5, Decl(classUsedBeforeInitializedVariables.ts, 4, 11))
|
||||
|
||||
p6?: string;
|
||||
>p6 : Symbol(Test.p6, Decl(classUsedBeforeInitializedVariables.ts, 5, 16))
|
||||
|
||||
p7 = {
|
||||
>p7 : Symbol(Test.p7, Decl(classUsedBeforeInitializedVariables.ts, 7, 16))
|
||||
|
||||
hello: (this.p6 = "string"),
|
||||
>hello : Symbol(hello, Decl(classUsedBeforeInitializedVariables.ts, 8, 10))
|
||||
>this.p6 : Symbol(Test.p6, Decl(classUsedBeforeInitializedVariables.ts, 5, 16))
|
||||
>this : Symbol(Test, Decl(classUsedBeforeInitializedVariables.ts, 0, 0))
|
||||
>directlyAssigned : Symbol(Test.directlyAssigned, Decl(classUsedBeforeInitializedVariables.ts, 4, 11))
|
||||
>p6 : Symbol(Test.p6, Decl(classUsedBeforeInitializedVariables.ts, 5, 16))
|
||||
|
||||
};
|
||||
|
||||
directlyAssigned: any = this.directlyAssigned;
|
||||
>directlyAssigned : Symbol(Test.directlyAssigned, Decl(classUsedBeforeInitializedVariables.ts, 10, 6))
|
||||
>this.directlyAssigned : Symbol(Test.directlyAssigned, Decl(classUsedBeforeInitializedVariables.ts, 10, 6))
|
||||
>this : Symbol(Test, Decl(classUsedBeforeInitializedVariables.ts, 0, 0))
|
||||
>directlyAssigned : Symbol(Test.directlyAssigned, Decl(classUsedBeforeInitializedVariables.ts, 10, 6))
|
||||
|
||||
withinArrowFunction: any = () => this.withinArrowFunction;
|
||||
>withinArrowFunction : Symbol(Test.withinArrowFunction, Decl(classUsedBeforeInitializedVariables.ts, 6, 50))
|
||||
>this.withinArrowFunction : Symbol(Test.withinArrowFunction, Decl(classUsedBeforeInitializedVariables.ts, 6, 50))
|
||||
>withinArrowFunction : Symbol(Test.withinArrowFunction, Decl(classUsedBeforeInitializedVariables.ts, 12, 50))
|
||||
>this.withinArrowFunction : Symbol(Test.withinArrowFunction, Decl(classUsedBeforeInitializedVariables.ts, 12, 50))
|
||||
>this : Symbol(Test, Decl(classUsedBeforeInitializedVariables.ts, 0, 0))
|
||||
>withinArrowFunction : Symbol(Test.withinArrowFunction, Decl(classUsedBeforeInitializedVariables.ts, 6, 50))
|
||||
>withinArrowFunction : Symbol(Test.withinArrowFunction, Decl(classUsedBeforeInitializedVariables.ts, 12, 50))
|
||||
|
||||
withinFunction: any = function () {
|
||||
>withinFunction : Symbol(Test.withinFunction, Decl(classUsedBeforeInitializedVariables.ts, 8, 62))
|
||||
>withinFunction : Symbol(Test.withinFunction, Decl(classUsedBeforeInitializedVariables.ts, 14, 62))
|
||||
|
||||
return this.withinFunction;
|
||||
};
|
||||
|
||||
withinObjectLiteral: any = {
|
||||
>withinObjectLiteral : Symbol(Test.withinObjectLiteral, Decl(classUsedBeforeInitializedVariables.ts, 12, 6))
|
||||
>withinObjectLiteral : Symbol(Test.withinObjectLiteral, Decl(classUsedBeforeInitializedVariables.ts, 18, 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.withinObjectLiteral] : Symbol([this.withinObjectLiteral], Decl(classUsedBeforeInitializedVariables.ts, 20, 32))
|
||||
>this.withinObjectLiteral : Symbol(Test.withinObjectLiteral, Decl(classUsedBeforeInitializedVariables.ts, 18, 6))
|
||||
>this : Symbol(Test, Decl(classUsedBeforeInitializedVariables.ts, 0, 0))
|
||||
>withinObjectLiteral : Symbol(Test.withinObjectLiteral, Decl(classUsedBeforeInitializedVariables.ts, 12, 6))
|
||||
>withinObjectLiteral : Symbol(Test.withinObjectLiteral, Decl(classUsedBeforeInitializedVariables.ts, 18, 6))
|
||||
|
||||
};
|
||||
|
||||
withinObjectLiteralGetterName: any = {
|
||||
>withinObjectLiteralGetterName : Symbol(Test.withinObjectLiteralGetterName, Decl(classUsedBeforeInitializedVariables.ts, 16, 6))
|
||||
>withinObjectLiteralGetterName : Symbol(Test.withinObjectLiteralGetterName, Decl(classUsedBeforeInitializedVariables.ts, 22, 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.withinObjectLiteralGetterName] : Symbol([this.withinObjectLiteralGetterName], Decl(classUsedBeforeInitializedVariables.ts, 24, 42))
|
||||
>this.withinObjectLiteralGetterName : Symbol(Test.withinObjectLiteralGetterName, Decl(classUsedBeforeInitializedVariables.ts, 22, 6))
|
||||
>this : Symbol(Test, Decl(classUsedBeforeInitializedVariables.ts, 0, 0))
|
||||
>withinObjectLiteralGetterName : Symbol(Test.withinObjectLiteralGetterName, Decl(classUsedBeforeInitializedVariables.ts, 16, 6))
|
||||
>withinObjectLiteralGetterName : Symbol(Test.withinObjectLiteralGetterName, Decl(classUsedBeforeInitializedVariables.ts, 22, 6))
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
withinObjectLiteralSetterName: any = {
|
||||
>withinObjectLiteralSetterName : Symbol(Test.withinObjectLiteralSetterName, Decl(classUsedBeforeInitializedVariables.ts, 22, 6))
|
||||
>withinObjectLiteralSetterName : Symbol(Test.withinObjectLiteralSetterName, Decl(classUsedBeforeInitializedVariables.ts, 28, 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.withinObjectLiteralSetterName] : Symbol([this.withinObjectLiteralSetterName], Decl(classUsedBeforeInitializedVariables.ts, 30, 42))
|
||||
>this.withinObjectLiteralSetterName : Symbol(Test.withinObjectLiteralSetterName, Decl(classUsedBeforeInitializedVariables.ts, 28, 6))
|
||||
>this : Symbol(Test, Decl(classUsedBeforeInitializedVariables.ts, 0, 0))
|
||||
>withinObjectLiteralSetterName : Symbol(Test.withinObjectLiteralSetterName, Decl(classUsedBeforeInitializedVariables.ts, 22, 6))
|
||||
>_ : Symbol(_, Decl(classUsedBeforeInitializedVariables.ts, 25, 49))
|
||||
>withinObjectLiteralSetterName : Symbol(Test.withinObjectLiteralSetterName, Decl(classUsedBeforeInitializedVariables.ts, 28, 6))
|
||||
>_ : Symbol(_, Decl(classUsedBeforeInitializedVariables.ts, 31, 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))
|
||||
>withinClassDeclarationExtension : Symbol(Test.withinClassDeclarationExtension, Decl(classUsedBeforeInitializedVariables.ts, 32, 6))
|
||||
>this.withinClassDeclarationExtension : Symbol(Test.withinClassDeclarationExtension, Decl(classUsedBeforeInitializedVariables.ts, 32, 6))
|
||||
>this : Symbol(Test, Decl(classUsedBeforeInitializedVariables.ts, 0, 0))
|
||||
>withinClassDeclarationExtension : Symbol(Test.withinClassDeclarationExtension, Decl(classUsedBeforeInitializedVariables.ts, 26, 6))
|
||||
>withinClassDeclarationExtension : Symbol(Test.withinClassDeclarationExtension, Decl(classUsedBeforeInitializedVariables.ts, 32, 6))
|
||||
|
||||
fromOptional = this.p5;
|
||||
>fromOptional : Symbol(Test.fromOptional, Decl(classUsedBeforeInitializedVariables.ts, 34, 100))
|
||||
>this.p5 : Symbol(Test.p5, Decl(classUsedBeforeInitializedVariables.ts, 4, 11))
|
||||
>this : Symbol(Test, Decl(classUsedBeforeInitializedVariables.ts, 0, 0))
|
||||
>p5 : Symbol(Test.p5, Decl(classUsedBeforeInitializedVariables.ts, 4, 11))
|
||||
|
||||
// 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))
|
||||
>assignedByArrowFunction : Symbol(Test.assignedByArrowFunction, Decl(classUsedBeforeInitializedVariables.ts, 36, 27))
|
||||
>this.assignedByFunction : Symbol(Test.assignedByFunction, Decl(classUsedBeforeInitializedVariables.ts, 40, 69))
|
||||
>this : Symbol(Test, Decl(classUsedBeforeInitializedVariables.ts, 0, 0))
|
||||
>assignedByFunction : Symbol(Test.assignedByFunction, Decl(classUsedBeforeInitializedVariables.ts, 32, 69))
|
||||
>assignedByFunction : Symbol(Test.assignedByFunction, Decl(classUsedBeforeInitializedVariables.ts, 40, 69))
|
||||
|
||||
assignedByFunction: any = (function () {
|
||||
>assignedByFunction : Symbol(Test.assignedByFunction, Decl(classUsedBeforeInitializedVariables.ts, 32, 69))
|
||||
>assignedByFunction : Symbol(Test.assignedByFunction, Decl(classUsedBeforeInitializedVariables.ts, 40, 69))
|
||||
|
||||
return this.assignedByFunction;
|
||||
})();
|
||||
|
|
|
@ -22,6 +22,27 @@ class Test {
|
|||
>p4 : number
|
||||
>0 : 0
|
||||
|
||||
p5?: number;
|
||||
>p5 : number
|
||||
|
||||
p6?: string;
|
||||
>p6 : string
|
||||
|
||||
p7 = {
|
||||
>p7 : { hello: string; }
|
||||
>{ hello: (this.p6 = "string"), } : { hello: string; }
|
||||
|
||||
hello: (this.p6 = "string"),
|
||||
>hello : string
|
||||
>(this.p6 = "string") : "string"
|
||||
>this.p6 = "string" : "string"
|
||||
>this.p6 : string
|
||||
>this : this
|
||||
>p6 : string
|
||||
>"string" : "string"
|
||||
|
||||
};
|
||||
|
||||
directlyAssigned: any = this.directlyAssigned;
|
||||
>directlyAssigned : any
|
||||
>this.directlyAssigned : any
|
||||
|
@ -95,6 +116,12 @@ class Test {
|
|||
>this : this
|
||||
>withinClassDeclarationExtension : any
|
||||
|
||||
fromOptional = this.p5;
|
||||
>fromOptional : number
|
||||
>this.p5 : number
|
||||
>this : this
|
||||
>p5 : number
|
||||
|
||||
// These error cases are ignored (not checked by control flow analysis)
|
||||
|
||||
assignedByArrowFunction: any = (() => this.assignedByFunction)();
|
||||
|
|
|
@ -5,6 +5,12 @@ class Test {
|
|||
p2 = this.p1;
|
||||
p3 = this.p4;
|
||||
p4 = 0;
|
||||
p5?: number;
|
||||
|
||||
p6?: string;
|
||||
p7 = {
|
||||
hello: (this.p6 = "string"),
|
||||
};
|
||||
|
||||
directlyAssigned: any = this.directlyAssigned;
|
||||
|
||||
|
@ -30,6 +36,8 @@ class Test {
|
|||
|
||||
withinClassDeclarationExtension: any = (class extends this.withinClassDeclarationExtension { });
|
||||
|
||||
fromOptional = this.p5;
|
||||
|
||||
// These error cases are ignored (not checked by control flow analysis)
|
||||
|
||||
assignedByArrowFunction: any = (() => this.assignedByFunction)();
|
||||
|
|
Loading…
Reference in a new issue