typescript typescript2.7

typescript - Obtener espacio de nombres de la clase



typescript2.7 (2)

¿Es posible dentro de TypeScript obtener el espacio de nombres de una clase?

namespace My.API.DTO { export class Something { // ID public id: number; public constructor() { } } }

Puedo escribir lo siguiente para obtener el nombre de la clase

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

Salidas

Alguna cosa

Quiero que la salida sea

Mi.API.DTO.Algo

Estoy abierto a usar una biblioteca de terceros para ayudar con esto. Tenga en cuenta que genero todas mis clases DTO de TypeScript a partir de sus contrapartes de C # utilizando el TypeWriter Visual Studio.


Desafortunadamente, creo que la respuesta es no. Si compara su código de TypeScript con el JavaScript compilado , puede ver que los espacios de nombres se implementan utilizando un patrón de módulo de JavaScript bastante estándar:

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 = {}));

Dado que esto es todo con lo que tiene que trabajar (toda la información de tipo de TypeScript desaparece durante la etapa de compilación), no creo que haya una forma sensata * de trabajar hacia atrás desde una clase para obtener su cadena de espacio de nombres.

Dependiendo de su caso de uso, puede usar algo como decoradores de clase para adjuntar metadatos a la clase y acceder a ellos en tiempo de ejecución. Esto solo funcionará si usted tiene el control de las clases que desea inspeccionar.


* Es posible que se recursivamente recorre todos los objetos en el ámbito global hasta que encuentre la ubicación de la función constructora de la clase. Por ejemplo, su clase de Something se puede encontrar (en el navegador) en window.My.API.DTO.Something .


Si tiene acceso al espacio de nombres de la raíz, My en su caso, puede parchear recursivamente todas las clases (en realidad todas las funciones) con un método auxiliar:

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

Solo debes tener en cuenta que esto parcha cualquier función dentro del árbol, ya que las clases de ES6 no son nada más. El inconveniente es que tendrá que parchear cada raíz de espacio de nombres individualmente, ya que el patch(window) probablemente causará un error de recursión y probablemente otros efectos secundarios no deseados.

Tenga en cuenta que, en lugar de utilizar la destrucción de objetos, también podría llamar a un patch así:

patch(My, ''My'');

Demo