Hva betyr `export as namespace` i en TypeScript .d.ts-fil?


Jeg har lest noen deklarasjonsfiler på DefinitelyTyped og har ofte kommet over filer som dette:

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

export = domready;
export as namespace domready;

Jeg forstår de to første linjene - deklarere en funksjon og eksportere den funksjonen som modulenobjekt. Men hva er den siste linjen? Trenger jeg dette i deklarasjonsfilen min? Hva gjør det?

Svar #1

Dette er en UMD-moduldeklarasjon.

Hvis du ikke er kjent med det allerede, er UMD et opprettelsesmønster som lar det samme JavaScript-biblioteket brukes som en global variabel (en som kan aksesseres hvor som helst) eller som et modul (en som spesifikt lastes inn ved kjøretid) avhengig av miljøet.

Mange biblioteker er skrevet med UMD-mønsteret. For eksempel kan du skrive

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

i nettleseren, men skriv kode slik i node.js:

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

Når du skriver en export-deklarasjon som export function parse, vet TypeScript at du beskriver et modul som i den andre kodeblokken. Men hvis biblioteket du skriver en .d.ts-fil for også lager en global variabel, kan du beskrive den globale variabelen ved å bruke UMD-moduldeklarasjonssyntaksen:

export as namespace the_global_identifier;

Noen UMD-biblioteker vil alltid lage en global, mens andre må importeres hvis de lastes i et miljø der et modulsystem er til stede. Generelt dokumenterer ikke biblioteker tydelig hvilken oppførsel de bruker, noe som betyr at forfattere av deklarasjonsfiler egentlig ikke vet hva de kan forvente, noe som betyr at TypeScript er konservativ og vil bare tillate tilgang til den globale identifikatoren hvis filen som refererer til den ikke er et modul.

Hvis du skriver en deklarasjonsfil og ikke er sikker på om biblioteket er UMD eller ikke, sjekk etter mønstre som ser slik ut:

(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');
    }
}));

Dette er den typiske UMD-lukten: mye typeof-sjekking for «exports», «module» og «define» etterfulgt av en tildeling til en «exports»-parameter gitt til en stor funksjonskropp. Hvis du ikke ser dette i bibliotekskoden, er det nesten helt sikkert ikke en UMD-modul, og du bør ikke skrive en export as namespace-erklæring.

Relaterte artikler