mirror of
https://github.com/microsoft/TypeScript.git
synced 2025-11-18 17:21:48 +00:00
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:
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user