You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Typescript AST如何获取断言类型并为未赋值类属性生成默认值

解决方案

你可以按照以下逻辑处理:

  1. 获取属性类型:不要通过symbol.valueDeclaration.kind做手动判断,直接使用TypeChecker提供的getTypeOfSymbolAtLocation方法,即可直接拿到属性的编译期类型。就算属性没有显式写类型注解(比如你提到的noKeyword场景),该方法也会自动返回any类型,完全覆盖边界场景。
  2. 判断属性是否已赋值:不要依赖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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.01 06:48:02