如何从AST将泛型解析为实际类型,用checker.isNullableType判断参数可空性?
如何将泛型类型展开为实际类型以检查可空性?
问题场景
给定以下TypeScript代码:
type Action1<T> = (arg1: T) => void; const fn: Action1<string | null> = (arg1: string | null): void => {}; fn(null);
尝试从函数调用的AST中获取参数的实际类型,用于通过checker.isNullableType检查可空性,但当前代码获取到的是泛型参数T,导致checker.isNullableType返回false,无法识别实际的string | null类型。
当前失效的代码:
var fnCallNode = sourceFile.statements[2].getChildAt(0).getChildAt(0); var fnType = checker.getTypeAtLocation(fnCallNode); console.log(checker.typeToString(fnType)); // "Action1<string | null>" var parameterTypeDeclaration = fnType.getCallSignatures()[0].getParameters()[0].declarations[0]; var parameterType = checker.getTypeAtLocation(parameterTypeDeclaration); console.log(checker.typeToString(parameterType)); // "T" console.log(checker.isNullableType(parameterType)); // false
解决方案
核心思路是直接从已实例化的泛型类型或调用签名中获取实际参数类型,而非访问泛型定义中的参数声明节点。
方法一:通过泛型类型实例的typeArguments获取
已实例化的泛型类型(如Action1<string | null>)会保留泛型参数的实际值,可通过typeArguments属性直接提取:
var fnCallNode = sourceFile.statements[2].getChildAt(0).getChildAt(0); var fnType = checker.getTypeAtLocation(fnCallNode); // 获取泛型参数T对应的实际类型 var actualParamType = fnType.typeArguments[0]; console.log(checker.typeToString(actualParamType)); // "string | null" console.log(checker.isNullableType(actualParamType)); // true
方法二:从调用签名中提取实例化后的参数类型
通过调用签名的参数符号,结合当前上下文获取实际类型:
var fnCallNode = sourceFile.statements[2].getChildAt(0).getChildAt(0); var fnType = checker.getTypeAtLocation(fnCallNode); var signature = fnType.getCallSignatures()[0]; // 获取第一个参数的实际类型 var paramSymbol = signature.parameters[0]; var actualParamType = checker.getTypeOfSymbolAtLocation(paramSymbol, fnCallNode); console.log(checker.typeToString(actualParamType)); // "string | null" console.log(checker.isNullableType(actualParamType)); // true
原因说明
之前的代码错误地访问了泛型定义(Action1<T>)中的参数声明节点,该节点对应的是未实例化的泛型参数T,而非实例化后的实际类型。上述两种方法均直接从已绑定实际类型的泛型实例或调用签名中获取值,因此能正确识别string | null的可空性。
内容的提问来源于stack exchange,提问作者wrager
相关产品推荐
相关产品推荐

