Home > Mobile >  TS Compiler API : Print complete property tree of a type
TS Compiler API : Print complete property tree of a type

Time:12-20

How to print the full property tree from the type of a variable? Let's take the following example,

interface Address{
   country: string;
}

interface Author{
  authorId: number;
  authorName:string;
  address: Address;
}

interface Book{
  bookId:string;
  title: string;
  author : Author;
}

A method in my code returns a value of type Book and I retrieved the type using checker.getReturnTypeOfSignature(methodSignature!). Now from this type, I need to create the property tree like,

[ 
   'bookId',
   'title',
   'author.authorId',
   'author.authorName',
   'author.address.country'
]

I tried to traverse the property tree with the following code,

const stack: any[] = [...bookType.getProperties()];
const props: any[] = [];

while (stack.length) {
  const prop = stack.pop();
  props.push(prop);
  if (checker.getTypeOfSymbolAtLocation(prop, node)) { //node is a ts.MethodDeclaration which returns a value of type Book
    stack.push(...checker.getTypeOfSymbolAtLocation(prop, node).getProperties());
  }
}

The above code works but it also reads the properties of in built types like string, number etc., ( toLocaleString, valueOf, toPrecision). I would like to extract the properties of custom types/interfaces and ignore the in built types.

CodePudding user response:

The above code works but it also reads the properties of in built types like string, number etc., ( toLocaleString, valueOf, toPrecision). I would like to extract the properties of custom types/interfaces and ignore the in built types.

This can be achieved by going from the type, to the symbol, then checking if the symbol links back to any declarations found in your project. For example:

// untested, but something along these lines
const type = checker.getTypeOfSymbolAtLocation(prop, node);
const isTypeInYourPoject = type.getSymbol()?.getDeclarations()?.some(d => {
  // Or you could check the file path is not
  // in the `node_modules/typescript/lib` folder.
  return isFilePathInYourProject(d.getSourceFile().fileName);
});

if (isTypeInYourPoject) {
  // do stuff...
}

You can also look at stuff like type.flags to tell if it's a type like string or number.

  • Related