从类中获取命名空间

时间:2018-02-08 15:38:27

标签: typescript typescript2.7

在TypeScript中是否可以获取类的命名空间?

namespace My.API.DTO {
    export class Something {

        // ID
        public id: number;

        public constructor() { }
    }
}

我可以编写以下内容来获取类名

console.log(My.API.DTO.Something.name);

输出

  

东西

我希望输出为

  

My.API.DTO.Something

我愿意使用第三方库来帮助解决这个问题。请注意我使用TypeWriter Visual Studio插件从C#对应物生成所有TypeScript DTO类。

2 个答案:

答案 0 :(得分:7)

不幸的是,我认为答案是否定的。 If you compare your TypeScript code to the compiled JavaScript,您可以看到命名空间是使用相当标准的JavaScript模块模式实现的:

var My;
(function (My) {
    var API;
    (function (API) {
        var DTO;
        (function (DTO) {
            var Something = /** @class */ (function () {
                function Something() {
                }
                return Something;
            }());
            DTO.Something = Something;
        })(DTO = API.DTO || (API.DTO = {}));
    })(API = My.API || (My.API = {}));
})(My || (My = {}));

由于这是您必须使用的所有内容(所有TypeScript类型信息在编译阶段都会消失),因此我认为没有任何理智的方法可以从类中向后工作以获取其命名空间链。

根据您的使用情况,您可以使用class decorators之类的内容将元数据附加到类并在运行时访问它。这只有在您控制要检查的类时才有效。


*有可能递归循环遍历全局范围内的所有对象,直到找到类的构造函数的位置。  例如,您可以在Something找到window.My.API.DTO.Something课程(在浏览器中)。

答案 1 :(得分:7)

如果您可以访问根命名空间 - My - 您可以使用辅助方法递归修补所有类(实际上所有函数):

const patch = (ns: object, path?: string) => {
    Object.keys(ns).forEach((key) => {
        const value = ns[key];
        const currentPath = path ? `${path}.${key}` : key;
        if (typeof value === 'object') {
            patch(value, currentPath);
        }
        if (typeof value === 'function') {
            Object.defineProperty(value, 'name', {
                value: currentPath,
                configurable: true,
            });
        }
    })
}

namespace My.API.DTO {
    export class Something {

        // ID
        public id: number;

        public constructor() { }
    }
}

patch({ My });

console.log(My.API.DTO.Something.name); // My.API.DTO.Something

你必须要知道,这会修补树中的任何函数,因为ES6类只不过了。缺点是您必须单独修补每个命名空间根,因为patch(window)很可能会导致过多的递归错误以及其他可能的副作用。

请注意,您可以像这样调用patch而不是使用对象解构:

patch(My, 'My');

<强> Demo