Typescript AST如何获取断言类型并为未赋值类属性生成默认值
解决方案
你可以按照以下逻辑处理:
- 获取属性类型:不要通过
symbol.valueDeclaration.kind做手动判断,直接使用TypeChecker提供的getTypeOfSymbolAtLocation方法,即可直接拿到属性的编译期类型。就算属性没有显式写类型注解(比如你提到的noKeyword场景),该方法也会自动返回any类型,完全覆盖边界场景。 - 判断属性是否已赋值:不要依赖
symbol.valueDeclaration,优先取symbol.declarations数组的第一个有效节点(valueDeclaration本质是该数组第一个元素的快捷访问,部分场景下会返回undefined,直接取declarations更稳妥)。如果节点类型是ts.PropertyDefinition,检查节点是否存在initializer属性即可判断是否已在声明阶段完成赋值。
完整实现代码
const typeChecker = program.getTypeChecker(); // 注意:原代码直接取调用表达式的类型拿到的是函数返回值,需要先取泛型实参 const callTypeArgs = callExpression.typeArguments; if (!callTypeArgs?.length) return; // 拿到泛型参数里的MyClass类型 const classType = typeChecker.getTypeAtLocation(callTypeArgs[0]); const generateResult: Record<string, any> = {}; classType.getProperties().forEach(symbol => { // 取属性声明节点 const propDeclaration = symbol.declarations?.[0] as ts.PropertyDefinition | undefined; if (!propDeclaration || !ts.isPropertyDefinition(propDeclaration)) return; // 已赋值的属性直接取初始化值 if (propDeclaration.initializer) { const initValue = typeChecker.getConstantValue(propDeclaration.initializer) ?? propDeclaration.initializer.getText(); generateResult[symbol.name] = initValue; return; } // 未赋值的属性先拿类型再生成默认值 const propType = typeChecker.getTypeOfSymbolAtLocation(symbol, propDeclaration); let defaultValue: any; if (typeChecker.isStringType(propType)) { defaultValue = 'I am generated'; } else if (typeChecker.isNumberType(propType)) { defaultValue = 0; } else if (typeChecker.isBooleanType(propType)) { defaultValue = false; } else { // any、自定义类型等其他场景可自定义默认规则 defaultValue = null; } generateResult[symbol.name] = defaultValue; });
补充说明
- 类转换为
InterfaceType后,所有属性的声明节点都可以在symbol.declarations数组中找到,不会出现节点缺失的问题 - 对于没有类型注解也没有初始化值的属性,
getTypeOfSymbolAtLocation会返回any类型,你可以单独为该场景设置专属默认值 - 如果初始化值不是字面量,而是其他表达式/变量引用,可以通过
typeChecker.getTypeAtLocation(propDeclaration.initializer)拿到值的类型做兼容处理
内容的提问来源于stack exchange,提问作者distante
相关产品推荐
相关产品推荐

