Using the TypeScript compiler API how can I get the actual, inferred type parameters for a call?

Viewed 68

I would like to use the TypeScript compiler API to get information about inferred types.

For example, in

// Two generic functions
function identity<T>(x: T): T { return x }
function copy<U>(x: Array<U>): Array<U> { return [...x] }

// Call to identity should have <T> bound to <Array<String>>
// based on context type.
let arr: Array<String> = identity([]);
// Call to identity should have <T> bound to <Array<String>>
// based on parameter type.
identity(arr);

// Calls to copy have parameters inferred like the two calls
// to identity, but <U> binds to <String>, not <Array<String>>.
let arrCopy: Array<String> = copy([]);
copy(arrCopy);

How can I get the bindings for type parameters like <T> and <U> for CallExpression nodes?

Is there a general way to get a computed type for a node? I see TypeChecker.getTypeOfSymbol, but most nodes, AFAICT, do not have symbols associated?


After looking at the above code in ts-ast-viewer.com it looks like TS treats [] as having type Array<never> which seems an odd choice if arrays are invariant.

But the below introduces an invariant class C<T> which does seem to propagate type parameter information from context to constructor call.

function identity<T>(x: T): T { return x }

class C<T> {
    x: T | null;
    private typeTag: "C" = "C";
    constructor(x: T | null = null) { this.x = x; }
}

let a: C<String> = identity(new C());
0 Answers
Related