diff --git a/jest.config.json b/jest.config.json index 0967ef424..0fdacad8f 100644 --- a/jest.config.json +++ b/jest.config.json @@ -1 +1,3 @@ -{} +{ + "testPathIgnorePatterns": ["types"] +} diff --git a/package.json b/package.json index 699e9e360..a04df0ec8 100644 --- a/package.json +++ b/package.json @@ -30,7 +30,7 @@ "start": "vite --config ./vite.config.js", "build-examples": "vite build --config ./vite.config.js", "lint": "eslint \"src/**/*.{js,jsx,ts}\" \"test/**/*.js\" \"example/*.{js,jsx}\" && tsc -p tsconfig.json --noEmit", - "test": "jest" + "test": "tsc --project tsconfig.test.json && jest" }, "repository": { "type": "git", diff --git a/src/plugins/three/ReorientationPlugin.d.ts b/src/plugins/three/ReorientationPlugin.d.ts index 41f4629ab..d495de557 100644 --- a/src/plugins/three/ReorientationPlugin.d.ts +++ b/src/plugins/three/ReorientationPlugin.d.ts @@ -1,4 +1,4 @@ -export class GLTFExtensionsPlugin { +export class ReorientationPlugin { constructor( options: { up: '+x' | '-x' | '+y' | '-y' | '+z' | '-z', diff --git a/src/three/TilesRenderer.d.ts b/src/three/TilesRenderer.d.ts index 1d8fff7af..c0ed55f8a 100644 --- a/src/three/TilesRenderer.d.ts +++ b/src/three/TilesRenderer.d.ts @@ -1,10 +1,25 @@ -import { Box3, Camera, Vector2, Matrix4, WebGLRenderer, Object3D, LoadingManager, Sphere } from 'three'; +import { Box3, Camera, Vector2, Matrix4, WebGLRenderer, Object3D, LoadingManager, Sphere, EventListener, EventDispatcher, BaseEvent } from 'three'; import { Tile } from '../base/Tile'; import { TilesRendererBase } from '../base/TilesRendererBase'; import { TilesGroup } from './TilesGroup'; import { Ellipsoid } from './math/Ellipsoid'; -export class TilesRenderer extends TilesRendererBase { +export interface TilesRendererEventMap { + 'add-camera': { camera: Camera }; + 'delete-camera': { camera: Camera }; + 'camera-resolution-change': {}; + 'load-tile-set': { tileSet: object, url: string }; + 'tiles-load-start': {}; + 'tiles-load-end': {}; + 'load-content': {}; + 'load-model': { scene: Object3D; tile: Tile }; + 'dispose-model': { scene: Object3D; tile: Tile }; + 'tile-visibility-change': { scene: Object3D; tile: Tile; visible: boolean }; + 'update-before': {}; + 'update-after': {}; +} + +export class TilesRenderer extends TilesRendererBase implements EventDispatcher { ellipsoid: Ellipsoid; autoDisableRendererCulling : boolean; @@ -28,9 +43,54 @@ export class TilesRenderer extends TilesRendererBase { forEachLoadedModel( callback : ( scene : Object3D, tile : Tile ) => void ) : void; - addEventListener( type: string, cb: ( e : object ) => void ); - hasEventListener( type: string, cb: ( e : object ) => void ); - removeEventListener( type: string, cb: ( e : object ) => void ); - dispatchEvent( e : object ); + /** + * Adds a listener to an event type. + * @param type The type of event to listen to. + * @param listener The function that gets called when the event is fired. + */ + addEventListener>( + type: T, + listener: EventListener + ): void; + addEventListener( + type: T, + listener: EventListener<{}, T, this> + ): void; + + /** + * Checks if listener is added to an event type. + * @param type The type of event to listen to. + * @param listener The function that gets called when the event is fired. + */ + hasEventListener>( + type: T, + listener: EventListener + ): boolean; + hasEventListener( + type: T, + listener: EventListener<{}, T, this> + ): boolean; + + /** + * Removes a listener from an event type. + * @param type The type of the listener that gets removed. + * @param listener The listener function that gets removed. + */ + removeEventListener>( + type: T, + listener: EventListener + ): void; + removeEventListener( + type: T, + listener: EventListener<{}, T, this> + ): void; + + /** + * Fire an event type. + * @param event The event that gets fired. + */ + dispatchEvent>( + event: BaseEvent & TEventMap[T] + ): void; } diff --git a/test/types/TilesRenderer.test.ts b/test/types/TilesRenderer.test.ts new file mode 100644 index 000000000..aec5ebbaa --- /dev/null +++ b/test/types/TilesRenderer.test.ts @@ -0,0 +1,37 @@ +import { Camera, Object3D } from 'three'; +import { Tile, TilesRenderer } from '../../src'; + +function addCamera( event: { camera: Camera } ) {} +function deleteCamera( event: { camera: Camera } ) {} +function emptyEvent( event: { } ) {} +function loadTileset( event: { tileSet: object, url: string } ) {} +function loadModel( event: { scene: Object3D; tile: Tile } ) {} +function disposeModel( event: { scene: Object3D; tile: Tile; } ) {} +function tileVisibilityChange( event: { scene: Object3D; tile: Tile; visible: boolean } ) {} + +function whatever( event: unknown ) {} + +// This function is not meant to be executed, but just here to +// guarantee that the exported types match what is expected. +// eslint-disable-next-line no-unused-vars +function typecheck( renderer: TilesRenderer ) { + + // Check events emitted by the TilesRenderer + renderer.addEventListener( 'add-camera', addCamera ); + renderer.addEventListener( 'delete-camera', deleteCamera ); + renderer.addEventListener( 'camera-resolution-change', emptyEvent ); + renderer.addEventListener( 'load-tile-set', loadTileset ); + renderer.addEventListener( 'tiles-load-start', emptyEvent ); + renderer.addEventListener( 'tiles-load-end', emptyEvent ); + renderer.addEventListener( 'load-content', emptyEvent ); + renderer.addEventListener( 'load-model', loadModel ); + renderer.addEventListener( 'dispose-model', disposeModel ); + renderer.addEventListener( 'tile-visibility-change', tileVisibilityChange ); + renderer.addEventListener( 'update-before', emptyEvent ); + renderer.addEventListener( 'update-after', emptyEvent ); + + // Check that we are still able to call an event type that is not + // known by the TilesRenderer itself. + renderer.addEventListener( 'my-unknown-event', whatever ); + +} diff --git a/tsconfig.test.json b/tsconfig.test.json new file mode 100644 index 000000000..dbf84b0e7 --- /dev/null +++ b/tsconfig.test.json @@ -0,0 +1,10 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "noEmit": true, + }, + "include": [ + // Type-based test files to check API + "test/types/" + ] +}