如何正确地将 JSDoc 与 Closure Compiler 一起使用以相同地重命名属性?

How to correctly use JSDoc with Closure Compiler to rename properties identically?

我有一个函数,它接受类似字典的对象并且必须提取一个特定的 属性 并遍历可能的嵌套子对象:

function process(obj){

    //extract ID
    let secret = obj.secret;
    delete obj.secret; // yes, I have to delete that property, not just set to null

    // do some stuff

    if (Array.isArray(obj.others)) {

        // Extract others
        let others = obj.others;
        delete obj.others; // yes, I have to delete that property too

        // Process children too
        others.forEach(foo);
    }
}

我用这个函数来处理对象:

class MyClass {

    contructor() {
        //init
    }

    getDictionary() {

        return {
            secret: 123,
            baz: 'baz',
            bar: 'bar',
            others: [{
                    secret: OtherClass,
                    forbar: 'foobar',
                    others: [{...},...]
                },{
                    ...
                }]
        };
    }

    parse() {
        return process(this.getDictionary());
    }
}

Closure 编译器总是将 process 函数中的 "obj.secret" 重命名为(类似于)"a.a",但并不总是将 "secret" 属性 在 getDictionary 返回的对象中。如果是这样,他们没有将 "secret" 属性 重命名为相同的。

我不想导出那些 - obj['secret'] : 我希望重命名它们。我在 Closure Compiler guide 中寻找 JSDoc 注释,但我不确定该怎么做。

特别是如何定义字典,有必填的"secret"属性(类型:数字或一些class),可选的"others"属性(是相同结构字典的数组)和零个或多个字符串属性。

您有 2 个选项:

禁用基于类型的优化

设置--use_types_for_optimization=false标志。任何同名的 属性 都将被一致地重命名 - 无论它们看起来是否相关。

实现接口

为编译器提供足够的类型信息,以便它识别属性是相关的并且必须一致重命名:

/** @interface */
function MyDictionary() {}

/** @type {number} */
MyDictionary.prototype.secret;

/** @type {MyDictionary} */
MyDictionary.prototype.others;

然后将类型注释添加到您的其他代码中:

/** @return {MyDictionary} */
getDictionary() { ... }

/** @param {MyDictionary} obj */
function process(obj){ ... }

您可能还需要对 getDictionary 方法返回的对象进行类型转换。