typescript - Exportera namnrymder i ambient-deklarationer samtidigt som man refererar till andra namnrymder


Jag försöker skapa en ambient typdeklaration för Turf.js. Den kan importeras från npm antingen med alla funktioner, eller styckvis, en modul i taget.

Jag har ett huvudnamnrymd som innehåller alla funktionsdeklarationer:

declare namespace turf {
    export function area(input: GeoJSON.Feature<any> | GeoJSON.FeatureCollection<any>): number;
    export function bearing(start: GeoJSON.Feature<GeoJSON.Point>, end: GeoJSON.Feature<GeoJSON.Point>): number;
    ...
    export function feature(geometry: GeoJSON.GeometryObject, properties?: any): GeoJSON.FeatureCollection<any>;
    export function point(coordinates: GeoJSON.Position, properties?: any): GeoJSON.Feature<GeoJSON.Point>;

}

För den monolitiska exporten kan jag göra detta:

declare module "turf" {
    export = turf;
}

Och för normala styckvisa modulexporter kan jag göra så här:

declare module "@turf/area" {
    export default turf.area;
}

declare module "@turf/bearing" {
    export default turf.bearing;
}

Vilket sedan kan användas så här:

import bearing from "@turf/bearing";

Turf-biblioteket har också en modul som heter @turf/helpers, som används på detta sätt:

import { feature, point } from "@turf/helpers"

Min fråga är, hur skriver jag typen för exporten av modulen "@turf/helpers"? Jag vill inte kopiera typdefinitionen, utan använda de som redan finns i turf-namnområdet.

Det närmaste jag har kunnat uppnå är detta:

declare module "@turf/helpers" {
    export = {
        feature: turf.feature,
        point: turf.point,
    }
}

Men eftersom jag inte exporterar en modul, måste jag använda import x=require(...)-formatet i min implementation:

import helpers = require("@turf/helpers");
const { feature, point } = helpers;
feature(...)

Svar #1

Detta löstes med hjälp av export import ...=...-konstruktionen.

(Sidnot: Jag lärde mig också att inte alla funktioner i @turf/helpers-paketet var tillgängliga i @turf, vilket kommer att illustreras med distanceToDegrees.)

Jag skapade ett nästlat namnrymd inom turf-namnrymden, och deklarerade sedan uttryckligen vilka deklarationer som skulle exporteras från helpers-namnrymden:

declare namespace turf {
    ...
    namespace helpers {
        // Should be imported as turf.feature and turf.point
        export function feature(geometry: GeoJSON.GeometryObject, properties?: any): GeoJSON.FeatureCollection<any>;
        export function point(coordinates: GeoJSON.Position, properties?: any): GeoJSON.Feature<GeoJSON.Point>;
        ...
        // Should not be included in turf, only able to be imported from @turf/helpers
        export function distanceToDegrees(distance: number, unit?: Unit): number;
    }

    export import feature = helpers.feature;
    export import point = helpers.point;
}

Den monolitiska moduldeklationen "turf" förblir densamma:

declare module "turf" {
    export = turf;
}

Och deklarationen av modulen "@turf/helpers" ser ut så här:

declare module "@turf/helpers" {
    import helpers = turf.helpers;
    export = helpers;
}

Så nu stöds båda användningsfallen:

import * as turf from "turf";

import { feature, distanceToDegrees } from "@turf/helpers";

let geometry = {
  "type": "Point",
  "coordinates": [
    67.5,
    32.84267363195431,
  ],
};

turf.feature(geometry); // OK 
feature(geometry); // OK
turf.distanceToDegrees(10) // NOT OK
distanceToDegrees(10); // OK