如何通过TypeScript编译器API获取调用点的推断类型参数
问题:获取TypeScript调用点处隐式推断的泛型类型参数
给定以下TypeScript代码:
type Ctor<T> = { new (): T } export function foo<T>(Ctor: Ctor<T>) { } class Bar { foo = 'what' } foo(Bar) // 此处T被隐式推断为Bar类型
尝试通过TypeScript编译器API获取foo(Bar)调用点处推断出的T类型时,遇到两个问题:
- 通过
typeChecker.getTypeAtLocation(node.expression)只能获取foo的声明类型,无法拿到调用点的推断类型参数; - 通过
node.typeArguments获取的值为空,因为类型参数并未显式传入。
解决方案
要获取隐式推断的泛型类型参数,需要借助TypeScript编译器API的解析签名(resolved signature),它包含了调用点处所有推断后的类型信息。具体实现步骤如下:
- 判断当前节点是否为调用表达式;
- 获取该调用表达式的解析签名,这是编译器完成类型推断后生成的签名;
- 从解析签名中提取推断后的泛型类型参数;
对应的代码示例:
import * as ts from "typescript"; // 假设已获取调用表达式节点node,以及typeChecker实例 if (ts.isCallExpression(node)) { // 获取调用的解析签名,包含推断后的类型信息 const resolvedSignature = typeChecker.getResolvedSignature(node); if (resolvedSignature) { // resolvedSignature.typeArguments 是推断出的泛型参数数组 if (resolvedSignature.typeArguments && resolvedSignature.typeArguments.length > 0) { // 取第一个泛型参数(即示例中的T) const inferredT = resolvedSignature.typeArguments[0]; // 将内部类型对象转换为可读字符串 const tTypeName = typeChecker.typeToString(inferredT); console.log(tTypeName); // 输出 "Bar" } } }
关键说明
getResolvedSignature(node):返回调用表达式经过类型推断后的签名,与函数原始声明签名不同,它包含了调用上下文的具体类型信息;resolvedSignature.typeArguments:即使调用时没有显式传入类型参数(node.typeArguments为空),这里也会包含编译器隐式推断出的类型参数数组;typeChecker.typeToString():用于将TypeScript内部类型对象转换为可读的字符串格式,方便查看或后续处理。
内容的提问来源于stack exchange,提问作者Avin Kavish
相关产品推荐
相关产品推荐

