Description
Right now the parent
property is optional on all AST nodes.
However in reality, it's always defined on all AST nodes, except for Program
, where it is missing.
This leads to a bunch of unnecessary ifs/optional chains/"trust me it's right" assertions, all of which "harm" the type safety, or are impossible to get coverage on (leading to istanbul ignore statements):
// this shouldn't happen, checking just in case
/* istanbul ignore if */ if (node.parent) {
// ...
}
// selector asserts this is correct
const parent = node.parent as TSESTree.VariableDeclaration;
if (node.parent?.type === AST_NODE_TYPES.VariableDeclaration) {
// ...
}
There is an issue with this, however.
typescript-estree
does not assign the parent property; this is done by ESLint as it traverses the AST at lint time.
So there are two solutions I can see:
- change
typescript-estree
so that it sets theparent
appropriately. - create a separate set of types for use within plugins, which correctly type the
parent
property.
As an aside, doing this would unlock a really awesome benefit wherein we could make all the types generic, allowing you to specify the expected parent type ahead of time:
interface BaseNode<TParent extends Node = Node> {
// ...
parent: TParent;
}
interface VariableDeclarator<TParent extends Node = Node> extends BaseNode<TParent> {}
interface Program extends BaseNode {
parent?: never;
}
This would be great for things like return values of functions which explicitly check parent types, and for eslint selectors that explicitly state the tree structure (VariableDeclaration > VariableDeclarator
).