Given the following Typescript declaration file:
interface CustomType1 {}
interface CustomType2 {}
declare function calc(): Shape<CustomType1>;
declare function calc2(): Shape<CustomType2>;
What is the cleanest way to retrieve CustomType1 argument in calc function signature?
I have this so far:
const fnd = sourceFile.getFunction('calc');
fnd.compilerNode.type.typeArguments[0].typeName //{text: "CustomType1"}
Using only the AST, the type argument node's text in the return type can be retrieved by getting the return type node, assuming it's a TypeReferenceNode, then getting its first type argument's text (using https://ts-ast-viewer.com helps to figure out what kind of node that is):
import { Project, TypeReferenceNode } from "ts-simple-ast";
// ...etc...
const typeReferenceNode = fnd.getReturnTypeNodeOrThrow() as TypeReferenceNode;
console.log(typeReferenceNode.getTypeArguments()[0].getText()); // CustomType1
You may not know what kind of node the return type is though, so using type guards can help in that scenario...
import { Project, TypeGuards } from "ts-simple-ast";
// ...etc...
const returnTypeNode = fnd.getReturnTypeNodeOrThrow();
if (TypeGuards.isTypeReferenceNode(returnTypeNode))
console.log(returnTypeNode.getTypeArguments()[0].getText()); // CustomType1
If you want to get the type using the type checker, then ensure Shape is defined in the code (no compile errors) and inspect the type returned when calling .getReturnType():
const sourceFile = project.createSourceFile("test.ts", `interface CustomType1 {}
interface CustomType2 {}
interface Shape<T> {}
declare function calc(): Shape<CustomType1>;
declare function calc2(): Shape<CustomType2>;`);
const fnd = sourceFile.getFunctionOrThrow("calc");
console.log(fnd.getReturnType().getTypeArguments()[0].getText()); // CustomType1
@dsherret thanks for the prompt and accurate response. As you pointed out TypeReferenceNode type is key here. I am guessing you can use the same technique for class declaration. I'll try it out.
declare class calc3 extends Shape<CustomType3> {};
btw ast-viewer is super cool!!!
Thanks!
Yeah, it's an expression with type arguments so using the ast alone you can just do:
const fnd = sourceFile.getClassOrThrow("calc3");
console.log(fnd.getExtendsOrThrow().getTypeArguments()[0].getText()); // Shape<CustomType3>