File
expressionWithType
|
Type
|
ts.ExpressionWithTypeArguments
|
import ts from 'typescript';
interface ClassResult {
symbol: ts.Symbol | undefined;
expressionWithType: ts.ExpressionWithTypeArguments;
node: ts.Node;
}
/**
* Helping utility to find all classes in a file that extend from something
*/
export const findInheritedClasses =
(checker: ts.TypeChecker) =>
(sourceFile: ts.SourceFile): ClassResult[] => {
const result: ClassResult[] = [];
ts.forEachChild(sourceFile, visit);
return result;
function visit(node: ts.Node) {
if (ts.isClassDeclaration(node) && node.name && node.heritageClauses) {
/**
* Find the Heritage Clause that matches `ExtendsKeyword` as we can potentially encounter
* other clauses like `implements` etc.
*/
const extendedClause = node.heritageClauses.find(
(item) => item.token === ts.SyntaxKind.ExtendsKeyword
);
if (!extendedClause) {
return;
}
const abstractBaseClass = extendedClause.types[0];
// that's the actual class
const classSymbol = checker.getSymbolAtLocation(node.name);
result.push({
symbol: classSymbol,
expressionWithType: abstractBaseClass,
node
});
}
}
};