Reputation: 33
Supposing we have a generic class or an interface:
interface A<T> {
prop1: T;
func2(): T;
}
interface B extends A<C> {
}
interface C {
}
We need to get the return type of the B.func2
method (not T
but C
).
The way described here works OK for props, but I can't figure out how to modify it for methods:
for (const statement of sourceFile.statements) {
if (!isInterface(statement))
continue;
if (!statement.heritageClauses?.length)
continue;
for (const heritageClause of statement.heritageClauses) {
for (const exprWithTypeArgs of heritageClause.types) {
const baseType = checker.getTypeAtLocation(exprWithTypeArgs);
for (const propSymbol of baseType.getProperties()) {
const resolvedType = checker.getTypeOfSymbolAtLocation(propSymbol, exprWithTypeArgs);
console.log(`${propSymbol.name} has type: ${resolvedType.symbol?.name}`);
// prints
// prop1 has type: C
// func2 has type: func1
for (const propDeclaration of propSymbol.declarations) {
if (!isSignatureDeclaration(propDeclaration))
continue;
const signature = checker.getSignatureFromDeclaration(propDeclaration);
const returnTypeSymbol = checker.getReturnTypeOfSignature(signature)?.symbol;
const resolvedReturnType = checker.getTypeOfSymbolAtLocation(returnTypeSymbol, exprWithTypeArgs);
console.log(`${propSymbol.name} return type: ${resolvedReturnType.symbol?.name}`);
// prints
// func2 return type: undefined
}
}
}
}
}
What is the correct way of getting resolved return type of a method?
Upvotes: 2
Views: 1270
Reputation: 106590
The TypeChecker#getSignaturesOfType
method allows for getting the signature of a type.
const bDecl = sourceFile.statements[1]; // obviously, improve this
const bType = typeChecker.getTypeAtLocation(bDecl);
const func2Symbol = bType.getProperty("func2")!;
const func2Type = typeChecker.getTypeOfSymbolAtLocation(func2Symbol, func2Symbol.valueDeclaration);
const func2Signature = checker.getSignaturesOfType(func2Type, ts.SignatureKind.Call)[0];
checker.typeToString(func2Signature.getReturnType()); // C
Upvotes: 2