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());