IlyaKhD
IlyaKhD

Reputation: 33

TypeScript Compiler API: Get resolved return type of a generic method

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

Answers (1)

David Sherret
David Sherret

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

Related Questions