Search code examples
typescriptabstract-syntax-treetypescript-eslint

Get super class reference in `@typescript-eslint/parser` AST


Given the following class hierarchy:

class Foo {
  fooMember = 1;
}

class Bar extends Foo {
  barMember = 2;
}

The AST output of @typescript-eslint/parser references the extends Foo statement as a superClass with the following properties:

superClass: Identifier {
  type: "Identifier",
  name: "Foo",
  range: [ 50 53 ]
}

Is it possible to extract the ClassDeclaration corresponding to Foo from this entry, and if so, how?
Is the same solution applicable if the extended class is imported?

Conceptually this should be possible, given that Typescript correctly infers errors such as public-private definition mismatch between parent-child classes etc.


Solution

  • This is possible, yes! But not through just the AST nodes as you're looking. It needs to be done with type information. You'll need to get the corresponding ts.Type for the backing node. See TypeScript's Using the Compiler API docs for more info on types.

    If you're working in a typed lint rule, then Custom Rules > Typed Rules has the docs you need. You'll want to use the typescript-eslint parser services to retrieve the ts.Type of the node:

    create(context) {
      return {
        'ClassDeclaration[superClass]'(node) {
          // 1. Grab the parser services for the rule
          const services = ESLintUtils.getParserServices(context);
    
          // 2. Find the TS type for the ES node
          const type = services.getTypeAtLocation(node.superClass);
        }
      };
    }
    

    If you're parsing code manually then you might need to use the compiler API more directly.

    Either way, once you have that ts.Type (the type variable in the code snippet), you may want to want to also retrieve the backing ts.Symbol. See Using the Compiler API > Type Checking APIs for explanations of symbols vs. types and the APIs around them.

    By the way, since this question was asked, the playground on typescript-eslint.io was created. It has views for the ESTree nodes, TypeScript nodes, backing TypeScript ts.Type types, and a few other niceties. Here's a playground link with the classes code. Cheers!