如何将扩展导入 ES6/Typescript 模块

How do I import extensions to an ES6/Typescript module

我正在尝试将一个简单的 Javascript 原型编写在一个带有嵌入式 <script> 标签的 .html 文件中,转换为使用 Typescript 编译的模块。

它使用的是 Leaflet,我很高兴能够通过

安装它
npm install leaflet

npm install --save @types/leaflet

通过

导入
import * as L from 'leaflet';

并通过例如

使用
var map = L.map('map').setView([-43.4175044, 172.185657], 8);

但是我也想使用这个 https://rawgit.com/jieter/Leaflet.encoded/master/Polyline.encoded.js Javascript 文件,它为主要的 Leaflet L 对象提供了一些扩展。

我试过通过

导入这个
import 'https://rawgit.com/jieter/Leaflet.encoded/master/Polyline.encoded.js'

但是当我尝试使用它时,例如

 var coordinates = L.Polyline.fromEncoded(encoded).getLatLngs();

我收到以下错误:

error TS2339: Property 'fromEncoded' does not exist on type 'typeof Polyline'.

我怎样才能让它工作?是否只是为这些扩展提供类型支持的问题?如果可以,我该怎么做?

由于 polyline-encoded 的工作方式,这很棘手:这个插件扩展了 Leaflet。因此,如果我们希望它像 JavaScript 中那样工作,我们需要扩展传单类型及其 1550 行!更有问题的是,每次我们要更新Leaflet,我们需要检查它的类型是否已经更新,并与polyline-encoded类型合并!

另一个潜在问题:在您的代码中,Leaflet 用于 ES6 模块,但 polyline-encoded 基于 IIFE,该 IIFE 更改了当前 Leaflet 对象 L ,混合新旧 JavaScript 方式。我很想知道它是否有效。

无论如何,我看到一个更安全的选择(但还没有测试):

  • 定义新类型 → 请参阅下面的 Leaflet.encoded.d.ts,以添加到您的项目中。
  • 强制转换 L 作为 Leaflet.encoded.d.ts 中定义的扩展类型:Lx.L;.
  • 每次使用 polyline-encoded 扩展时,请使用 Lx 而不是 L

您的代码改编:

import * as L from 'leaflet';
import 'https://rawgit.com/jieter/Leaflet.encoded/master/Polyline.encoded.js';

const Lx = L as any as Lx.L;

const map = L.map('map').setView([-43.4175044, 172.185657], 8);

const coordinates = Lx.Polyline.fromEncoded('...').getLatLngs();

Leaflet.encoded.d.ts:

// Type definitions for Leaflet polyline-encoded 0.0.8
// Project: https://github.com/jieter/Leaflet.encoded
// Definitions by: Romain Deneau <https://github.com/rdeneau>
// TypeScript Version: 2.5

import * as Leaflet from 'leaflet';

export as namespace Lx;

export interface L {
    PolylineUtil: PolylineUtil;
    Polyline: Polyline;
    Polygon: Polygon;
}

// -- PolylineUtil plugin ---------------------------------

export interface PolylineUtilOptions {
    precision: number;
    factor: number;
    dimension: number;
}

export type LatLngTuple = [number, number];

export interface PolylineUtil {
    /**
     * Decode the string `encoded` to an array of `[lat, lng]`-arrays.
     */
    decode(encoded: string, options?: number|PolylineUtilOptions): LatLngTuple[];

    /**
     * Encode an array of `L.LatLng` objects, or an array of arrays.
     */
    encode(points: Leaflet.LatLng[]|LatLngTuple[], options?: number|PolylineUtilOptions): string;
}

// -- Polyline/Polygon extensions -------------------------

export class Polyline extends Leaflet.Polyline {
    /**
     * Return an encoded string for the current Polyline.
     */
    encodePath(): string;

    /**
     * Construct a new `L.Polyline` from a string, with optional `options` object.
     * Backslashes in strings should be properly escaped.
     */
    fromEncoded(encoded: string, options?: Leaflet.PolylineOptions): Leaflet.Polyline;
}

export class Polygon extends Leaflet.Polygon {
    /**
     * Return an encoded string for the current Polygon.
     */
    encodePath(): string;

    /**
     * Construct a new `L.Polygon` from a string, with optional `options` object.
     * Backslashes in strings should be properly escaped.
     */
    fromEncoded(encoded: string, options?: Leaflet.PolylineOptions): Leaflet.Polygon;
}

如果有效,甚至可以共享此类型,将它们提交给 DefinitelyTyped repository