Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix typings issues in 3.2.0 #2898

Merged
merged 17 commits into from
Jul 24, 2023
Merged
Show file tree
Hide file tree
Changes from 9 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion build/generate-typings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ if (!fs.existsSync('dist')) {

console.log('Starting bundling types');
const outputFile = './dist/maplibre-gl.d.ts';
childProcess.execSync(`dts-bundle-generator --umd-module-name=maplibregl -o ${outputFile} ./src/index.ts`);
childProcess.execSync(`dts-bundle-generator --umd-module-name=maplibregl -o ${outputFile} ./src/index.ts --project tsconfig.typegen.json`);
neodescis marked this conversation as resolved.
Show resolved Hide resolved
let types = fs.readFileSync(outputFile, 'utf8');
// Classes are not exported but should be since this is exported as UMD - fixing...
types = types.replace(/declare class/g, 'export declare class');
Expand Down
3 changes: 1 addition & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
"@types/mapbox__point-geometry": "^0.1.2",
"@types/mapbox__vector-tile": "^1.3.0",
"@types/pbf": "^3.0.2",
"@types/supercluster": "^7.1.0",
HarelM marked this conversation as resolved.
Show resolved Hide resolved
"earcut": "^2.2.4",
"geojson-vt": "^3.2.1",
"gl-matrix": "^3.4.3",
Expand Down Expand Up @@ -69,7 +70,6 @@
"@types/react-dom": "^18.2.6",
"@types/request": "^2.48.8",
"@types/shuffle-seed": "^1.1.0",
"@types/supercluster": "^7.1.0",
"@types/window-or-global": "^1.0.4",
"@typescript-eslint/eslint-plugin": "^5.61.0",
"@typescript-eslint/parser": "^5.62.0",
Expand Down Expand Up @@ -175,7 +175,7 @@
"benchmark": "npm run tsnode test/bench/run-benchmarks.ts",
"gl-stats": "npm run tsnode test/bench/gl-stats.ts",
"prepare": "npm run codegen",
"typecheck": "tsc --noEmit && tsc --project tsconfig.dist.json",
"typecheck": "tsc --noEmit && tsc --project tsconfig.typecheck.json",
"tsnode": "node --experimental-loader=ts-node/esm --no-warnings"
},
"files": [
Expand Down
3 changes: 1 addition & 2 deletions src/ui/hash.ts
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,5 @@ export class Hash {
/**
* Mobile Safari doesn't allow updating the hash more than 100 times per 30 seconds.
*/
_updateHash = throttle(this._updateHashUnthrottled, 30 * 1000 / 100);

_updateHash: () => ReturnType<typeof setTimeout> = throttle(this._updateHashUnthrottled, 30 * 1000 / 100);
HarelM marked this conversation as resolved.
Show resolved Hide resolved
}
56 changes: 45 additions & 11 deletions src/ui/map.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1367,8 +1367,8 @@ export class Map extends Camera {
* when the cursor enters a visible portion of the specified layer from outside that layer or outside the map canvas.
* @param layer - The ID of a style layer or a listener if no ID is provided. Event will only be triggered if its location
* is within a visible feature in this layer. The event will have a `features` property containing
* an array of the matching features. If `layerIdOrListener` is not supplied, the event will not have a `features` property.
* Please note that many event types are not compatible with the optional `layerIdOrListener` parameter.
* an array of the matching features. If `layer` is not supplied, the event will not have a `features` property.
* Please note that many event types are not compatible with the optional `layer` parameter.
* @param listener - The function to be called when the event is fired.
* @returns `this`
* @example
Expand Down Expand Up @@ -1411,21 +1411,27 @@ export class Map extends Camera {
* @see [Create a hover effect](https://maplibre.org/maplibre-gl-js/docs/examples/hover-styles/)
* @see [Create a draggable marker](https://maplibre.org/maplibre-gl-js/docs/examples/drag-a-point/)
*/
on(type: keyof MapEventType | string, listener: Listener): this;
on<T extends keyof MapLayerEventType>(
type: T,
layer: string,
listener: (ev: MapLayerEventType[T] & Object) => void,
): Map;
/**
* Overload of the `on` method that allows to listen to events without specifying a layer.
* @event
* @param type - The type of the event.
* @param listener - The listener callback.
* @returns `this`
*/
on<T extends keyof MapEventType>(type: T, listener: (ev: MapEventType[T] & Object) => void): this;
/**
* This is an overload of the `on` method that allows to listen to events based on the `layerId`
* Overload of the `on` method that allows to listen to events without specifying a layer.
* @event
* @param type - The type of the event.
* @param layerIdOrListener - The ID of the layer.
* @param listener - The listener callback.
* @returns `this`
*/
on(type: keyof MapEventType | string, listener: Listener): this;
on(type: keyof MapEventType | string, layerIdOrListener: string | Listener, listener?: Listener): this {
if (listener === undefined) {
return super.on(type, layerIdOrListener as Listener);
Expand All @@ -1445,7 +1451,7 @@ export class Map extends Camera {
}

/**
* Adds a listener that will be called only once to a specified event type occurring on features in a specified style layer.
* Adds a listener that will be called only once to a specified event type, optionally limited to features in a specified style layer.
*
* @event
* @param type - The event type to listen for; one of `'mousedown'`, `'mouseup'`, `'click'`, `'dblclick'`,
Expand All @@ -1460,13 +1466,27 @@ export class Map extends Camera {
* @param listener - The function to be called when the event is fired.
* @returns `this` if listener is provided, promise otherwise to allow easier usage of async/await
*/
once(type: keyof MapEventType | string, listener?: Listener): this | Promise<any>;
once<T extends keyof MapLayerEventType>(
type: T,
layer: string,
listener?: (ev: MapLayerEventType[T] & Object) => void,
): this | Promise<MapLayerEventType[T] & Object>;
/**
* Overload of the `once` method that allows to listen to events without specifying a layer.
* @event
* @param type - The type of the event.
* @param listener - The listener callback.
* @returns `this`
*/
once<T extends keyof MapEventType>(type: T, listener?: (ev: MapEventType[T] & Object) => void): this | Promise<any>;
/**
* Overload of the `once` method that allows to listen to events without specifying a layer.
* @event
* @param type - The type of the event.
* @param listener - The listener callback.
* @returns `this`
*/
once(type: keyof MapEventType | string, listener?: Listener): this | Promise<any>;
HarelM marked this conversation as resolved.
Show resolved Hide resolved
once(type: keyof MapEventType | string, layerIdOrListener: string | Listener, listener?: Listener): this | Promise<any> {

if (listener === undefined) {
Expand All @@ -1483,21 +1503,35 @@ export class Map extends Camera {
}

/**
* Removes an event listener for layer-specific events previously added with `Map#on`.
* Removes an event listener for events previously added with `Map#on`.
*
* @event
* @param type - The event type previously used to install the listener.
* @param layerIdOrListener - The layer ID or listener previously used to install the listener.
* @param listener - (optional) The function previously installed as a listener.
* @param layer - The layer ID or listener previously used to install the listener.
* @param listener - The function previously installed as a listener.
* @returns `this`
*/
off(type: keyof MapEventType | string, listener: Listener): this;
off<T extends keyof MapLayerEventType>(
type: T,
layer: string,
listener: (ev: MapLayerEventType[T] & Object) => void,
): this;
/**
* Overload of the `off` method that allows to listen to events without specifying a layer.
* @event
* @param type - The type of the event.
* @param listener - The function previously installed as a listener.
* @returns `this`
*/
off<T extends keyof MapEventType>(type: T, listener: (ev: MapEventType[T] & Object) => void): this;
/**
* Overload of the `off` method that allows to listen to events without specifying a layer.
* @event
* @param type - The type of the event.
* @param listener - The function previously installed as a listener.
* @returns `this`
*/
off(type: keyof MapEventType | string, listener: Listener): this;
off(type: keyof MapEventType | string, layerIdOrListener: string | Listener, listener?: Listener): this {
if (listener === undefined) {
return super.off(type, layerIdOrListener as Listener);
Expand Down
76 changes: 76 additions & 0 deletions src/ui/map_events.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@ import {createMap, beforeMapTest} from '../util/test/util';
import {MapGeoJSONFeature} from '../util/vectortile_to_geojson';
import {MapLayerEventType, MapLibreEvent} from './events';

type IsAny<T> = 0 extends T & 1 ? T : never;
HarelM marked this conversation as resolved.
Show resolved Hide resolved
type NotAny<T> = T extends IsAny<T> ? never : T;
function assertNotAny<T>(_x: NotAny<T>) { }

beforeEach(() => {
beforeMapTest();
});
Expand Down Expand Up @@ -170,6 +174,20 @@ describe('map events', () => {
expect(handler.onMove).toHaveBeenCalledTimes(1);
});

test('Map#on allows a listener to infer the event type ', () => {
const map = createMap();

const spy = jest.fn();
map.on('mousemove', (event) => {
assertNotAny(event);
HarelM marked this conversation as resolved.
Show resolved Hide resolved
const {lng, lat} = event.lngLat;
spy({lng, lat});
});

simulate.mousemove(map.getCanvas());
expect(spy).toHaveBeenCalledTimes(1);
});

test('Map#off removes a delegated event listener', () => {
const map = createMap();

Expand Down Expand Up @@ -244,6 +262,64 @@ describe('map events', () => {
expect(spyB).not.toHaveBeenCalled();
});

test('Map#off calls an event listener with no type arguments, defaulting to \'unknown\' originalEvent type', () => {
const map = createMap();

const handler = {
onMove: function onMove(_event: MapLibreEvent) {}
};

jest.spyOn(handler, 'onMove');

map.off('move', (event) => handler.onMove(event));
map.jumpTo({center: {lng: 10, lat: 10}});

expect(handler.onMove).toHaveBeenCalledTimes(0);
});

test('Map#off allows a listener to infer the event type ', () => {
const map = createMap();

const spy = jest.fn();
map.off('mousemove', (event) => {
assertNotAny(event);
const {lng, lat} = event.lngLat;
spy({lng, lat});
});

simulate.mousemove(map.getCanvas());
expect(spy).toHaveBeenCalledTimes(0);
});

test('Map#once calls an event listener with no type arguments, defaulting to \'unknown\' originalEvent type', () => {
const map = createMap();

const handler = {
onMoveOnce: function onMoveOnce(_event: MapLibreEvent) {}
};

jest.spyOn(handler, 'onMoveOnce');

map.once('move', (event) => handler.onMoveOnce(event));
map.jumpTo({center: {lng: 10, lat: 10}});

expect(handler.onMoveOnce).toHaveBeenCalledTimes(1);
});

test('Map#once allows a listener to infer the event type ', () => {
const map = createMap();

const spy = jest.fn();
map.once('mousemove', (event) => {
assertNotAny(event);
const {lng, lat} = event.lngLat;
spy({lng, lat});
});

simulate.mousemove(map.getCanvas());
expect(spy).toHaveBeenCalledTimes(1);
});

(['mouseenter', 'mouseover'] as (keyof MapLayerEventType)[]).forEach((event) => {
test(`Map#on ${event} does not fire if the specified layer does not exist`, () => {
const map = createMap();
Expand Down
2 changes: 1 addition & 1 deletion tsconfig.dist.json → tsconfig.typecheck.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"extends": "./tsconfig.json",
"compilerOptions": {
"strict": true,
"strict": true
},
"include": [
"dist/maplibre-gl.d.ts"
Expand Down
9 changes: 9 additions & 0 deletions tsconfig.typegen.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
neodescis marked this conversation as resolved.
Show resolved Hide resolved
"extends": "./tsconfig.json",
"compilerOptions": {
"types": [
"geojson",
"offscreencanvas"
]
}
}