Pesquisa de site

O que significa `export as namespace` em um arquivo .d.ts do TypeScript?


Tenho lido alguns arquivos de declaração no DefinitelyTyped e muitas vezes me deparei com arquivos como este:

declare function domready(callback: () => any) : void;

export = domready;
export as namespace domready;

Eu entendo as duas primeiras linhas - declarar uma função e exportar essa função como o objeto do módulo. Mas qual é a última linha? Eu preciso disso no meu arquivo de declaração? O que isso faz?

Resposta #1

Esta é uma declaração de módulo UMD.

Se você ainda não está familiarizado, UMD é um padrão de criação que permite que a mesma biblioteca JavaScript seja usada como uma variável global (uma que pode ser acessada em qualquer lugar) ou como um módulo (um que é especificamente carregado em tempo de execução), dependendo do ambiente.

Muitas bibliotecas são escritas com o padrão UMD. Por exemplo, você pode escrever

moment.parse("12-31-2017")

no navegador, mas escreva código assim no node.js:

const m = require("moment");
m.parse("12-31-2017")

Quando você escreve uma declaração export como export function parse, o TypeScript sabe que você está descrevendo um módulo como no segundo bloco de código. Mas se a biblioteca para a qual você está escrevendo um arquivo .d.ts também cria uma variável global, você pode descrever essa variável global usando a sintaxe de declaração de módulo UMD:

export as namespace the_global_identifier;

Algumas bibliotecas UMD vão sempre criar um global, enquanto outras devem ser importadas se forem carregadas em um ambiente onde um sistema de módulos está presente. Em geral, as bibliotecas não documentam claramente qual comportamento usam, o que significa que os autores de arquivos de declaração realmente não sabem o que esperar, o que significa que o TypeScript é conservador e só permitirá acesso ao identificador global se o arquivo que o referencia não for um módulo.

Se você está escrevendo um arquivo de declaração e não tem certeza se a biblioteca é UMD ou não, verifique padrões que se parecem com isto:

(function (global, factory) {
  typeof exports === 'object' && typeof module !== 'undefined' ?     factory(exports) :
  typeof define === 'function' && define.amd ? define(['exports'], factory) :
  (factory((global.mymodule = global.mymodule || {})));
}(this, function (exports) { 'use strict';
    function myFunction() {
        console.log('hello world');
    }
}));

Este é o cheiro característico de UMD: muitas verificações com typeof para "exports", "module" e "define" seguidas de uma atribuição a um parâmetro "exports" passado para um grande corpo de função. Se você não vir isso no código da biblioteca, quase certamente não é um módulo UMD e você não deve escrever uma declaração export as namespace.

Artigos relacionados