我正在为Leaflet.Editable包开发一组DefinitelyTyped的定义。Leaflet值得注意的是,它使用部分自定义的类实现,以允许在纯JavaScript中扩展现有类型,如此处所示。只需import 'Leaflet.Editable'
在代码中的任意位置调用即可为现有的Leaflet类添加新功能,例如启用和禁用某些图层的编辑的功能。
它不是在TypeScript中实现的,因此键入是在@ types / leaflet中实现的,因此我正在开发的包(@ types / leaflet-editable)必须导入传单名称空间并扩展现有类型。
我必须扩展现有的类型,而不是添加新的类型,因为还有其他使用这些类型的库(例如react-leaflet)。
例如,通过扩展MapOptions
类型(通过合并接口),我能够为react-leaflet
的MapComponent
组件添加新属性,因为它的道具可以扩展Leaflet.MapOptions
。如果要创建一个新类型,EditableMapOptions
则不会对其进行扩展react-leaflet
,因此无法将这些属性添加到中MapComponent
。
我能够扩展几个现有的接口,并添加新的接口,例如VertexEventHandlerFn
(代表提供的事件回调VertexEvent
)。
问题是如何@types/leaflet
实现map.on('click', (event: LeafletEvent) => {})
功能。这是DefinitelyTyped回购的一个片段:
export abstract class Evented extends Class {
/**
* Adds a listener function (fn) to a particular event type of the object.
* You can optionally specify the context of the listener (object the this
* keyword will point to). You can also pass several space-separated types
* (e.g. 'click dblclick').
*/
// tslint:disable:unified-signatures
on(type: string, fn: LeafletEventHandlerFn, context?: any): this;
on(type: 'baselayerchange' | 'overlayadd' | 'overlayremove',
fn: LayersControlEventHandlerFn, context?: any): this;
on(type: 'layeradd' | 'layerremove',
fn: LayerEventHandlerFn, context?: any): this;
...
如您所见,它使用一个抽象类,该类为用户何时包含多个用空格分隔的事件以及几个特定事件(当提供特定参数时,为其事件处理程序包括正确的类型)提供了通用定义。
我想向其中添加函数,但找不到任何方法可以向现有抽象类添加其他重载。这里要注意的是,所有这些重载on
都由Leaflet中的同一行代码实现,因此此处不存在通过向抽象类添加新方法(以后不会由关联的JavaScript实现)所面临的问题。
我只是尝试尝试重新声明abstract class Evented
向其添加更多方法,但TypeScript告诉我它已经定义。我的研究仅发现TypeScript文档,该文档指示我应该使用mixins,因为我需要修改现有的类,而创建一个新的类并不能解决问题,所以我不能这样做。
从模块扩充的文档中可能不清楚,但是如果您想合并到一个named的实例类型中class
,可以通过添加interface
与相同的名字来实现class
。当您编写时class Foo {}
,它将类型命名Foo
为接口,您可以将其合并。例如:
import { Draggable, LeafletEvent } from 'leaflet';
interface PeanutButterEvent extends LeafletEvent {
chunky: boolean
}
declare module 'leaflet' {
interface Evented {
on(type: "peanut-butter", fn: (x: PeanutButterEvent) => void): this;
}
}
const draggable = new Draggable(new HTMLElement()) // whatever
draggable.on("peanut-butter", e => console.log(e.chunky ? "Chunky" : "Creamy")); // ok
draggable.on("resize", e => console.log(e.oldSize)); // still works
在这里,我on()
为interface
named添加了另一个重载Evented
。
另一方面,如果您想合并为的静态类型,则class
可以通过添加namespace
与相同名称的来实现class
。当您编写时class Foo {}
,它会将命名Foo
为值的值视为一个名称空间,您可以将其合并到其中。例如:
import { Draggable, Evented } from 'leaflet';
declare module 'leaflet' {
namespace Evented {
export function hello(): void;
}
}
Evented.hello = () => console.log("hello"); // implement if you want
Draggable.hello(); // okay
Draggable.mergeOptions({}); // still works
在这里,我将另一个静态方法添加hello()
到namespace
named中Evented
。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句