If you want to do this from scratch...
On a high level, one way of doing it is to:
Figure out how to get the SourceFile
node using the compiler api of your file. That requires a bit of an explanation in itself.
From there, use the api's forEachChild
function to loop over all the nodes in the file and find the node with a kind
of SyntaxKind.ClassDeclaration
and .name property with text Bar
.
Then loop over all the children of the class by again using the api's forEachChild
function and get the ones that has the kind SyntaxKind.MethodDeclaration
and .name property with text foo
.
To get the parameters, you will need to loop over the method node's parameters
property.
Then for each parameter node, to get the name you can call .getText()
on the .name
property.
You can tell if the parameter is optional by doing:
const parameterDeclaration = parameterNode as ts.ParameterDeclaration;
const isOptional = parameterDeclaration.questionToken != null || parameterDeclaration.initializer != null || parameterDeclaration.dotDotDotToken != null;
Or you could use the TypeChecker
's isOptionalParameter
method.
To get its default expression, you will just have to check the initializer
property:
propertyDeclaration.initializer;
To get the type use the TypeChecker
's getTypeOfSymbolAtLocation
method and pass in the symbol of the node... that gets a little bit complicated so I won't bother explaining it (think about how it's different with union types and such).
Don't do it from scratch...
I've created a wrapper around the TypeScript compiler api. Just use this code with ts-simple-ast (edit: Previously this talked about my old ts-type-info library, but ts-simple-ast is much better):
import { Project } from "ts-morph";
// read more about setup here:
// https://ts-morph.com/setup/adding-source-files
const project = new Project({ tsConfigFilePath: "tsconfig.json" });
const sourceFile = project.getSourceFileOrThrow("src/Foo.ts");
const method = sourceFile.getClassOrThrow("Bar").getInstanceMethodOrThrow("foo");
Once you have the method, it's very straightforward to get all the information you need from its parameters:
console.log(method.getName()); // foo
for (const param of method.getParameters()) {
console.log(param.getName());
console.log(param.getType().getText());
console.log(param.isOptional());
console.log(param.getInitializer() != null);
}