From 590dcdb7153a412dc2ed5bce90cccae4a6980028 Mon Sep 17 00:00:00 2001 From: Adrien Crivelli Date: Wed, 8 May 2024 12:24:55 +0700 Subject: [PATCH] Limit usage of `any` --- README.md | 6 ++--- projects/demo-app/src/app/app.component.ts | 8 +++--- .../lib/component/image-cropper.component.ts | 26 +++++++++++------- .../lib/interfaces/basic-event.interface.ts | 4 +++ .../lib/services/cropper-position.service.ts | 27 ++++++++++++++----- .../src/lib/utils/keyboard.utils.ts | 4 ++- 6 files changed, 50 insertions(+), 25 deletions(-) create mode 100644 projects/ngx-image-cropper/src/lib/interfaces/basic-event.interface.ts diff --git a/README.md b/README.md index 7cd8b58..846693b 100644 --- a/README.md +++ b/README.md @@ -40,15 +40,15 @@ import { DomSanitizer } from '@angular/platform-browser'; imports: [ImageCropperComponent] }) export class YourComponent { - imageChangedEvent: any = ''; - croppedImage: any = ''; + imageChangedEvent: Event | null = null; + croppedImage: SafeUrl = ''; constructor( private sanitizer: DomSanitizer ) { } - fileChangeEvent(event: any): void { + fileChangeEvent(event: Event): void { this.imageChangedEvent = event; } imageCropped(event: ImageCroppedEvent) { diff --git a/projects/demo-app/src/app/app.component.ts b/projects/demo-app/src/app/app.component.ts index 5ad1776..5daebac 100644 --- a/projects/demo-app/src/app/app.component.ts +++ b/projects/demo-app/src/app/app.component.ts @@ -1,6 +1,6 @@ import { Component } from '@angular/core'; import { Dimensions, ImageCroppedEvent, ImageTransform, ImageCropperComponent } from 'ngx-image-cropper'; -import { DomSanitizer } from '@angular/platform-browser'; +import {DomSanitizer, SafeUrl} from '@angular/platform-browser'; import { NgIf } from '@angular/common'; import { FormsModule } from "@angular/forms"; @@ -12,8 +12,8 @@ import { FormsModule } from "@angular/forms"; imports: [NgIf, FormsModule, ImageCropperComponent] }) export class AppComponent { - imageChangedEvent: any = ''; - croppedImage: any = ''; + imageChangedEvent: Event | null = null; + croppedImage: SafeUrl = ''; canvasRotation = 0; rotation?: number; translateH = 0; @@ -35,7 +35,7 @@ export class AppComponent { ) { } - fileChangeEvent(event: any): void { + fileChangeEvent(event: Event): void { this.loading = true; this.imageChangedEvent = event; } diff --git a/projects/ngx-image-cropper/src/lib/component/image-cropper.component.ts b/projects/ngx-image-cropper/src/lib/component/image-cropper.component.ts index e1ae2a1..6c817ad 100644 --- a/projects/ngx-image-cropper/src/lib/component/image-cropper.component.ts +++ b/projects/ngx-image-cropper/src/lib/component/image-cropper.component.ts @@ -30,6 +30,7 @@ import { getEventForKey, getInvertedPositionForKey, getPositionForKey } from '.. import { first, takeUntil } from 'rxjs/operators'; import { fromEvent, merge } from 'rxjs'; import { NgIf } from '@angular/common'; +import {BasicEvent} from "../interfaces/basic-event.interface"; @Component({ selector: 'image-cropper', @@ -59,7 +60,7 @@ export class ImageCropperComponent implements OnChanges, OnInit { @ViewChild('wrapper', {static: true}) wrapper!: ElementRef; @ViewChild('sourceImage', {static: false}) sourceImage!: ElementRef; - @Input() imageChangedEvent?: any; + @Input() imageChangedEvent?: Event | null; @Input() imageURL?: string; @Input() imageBase64?: string; @Input() imageFile?: File; @@ -194,8 +195,13 @@ export class ImageCropperComponent implements OnChanges, OnInit { } } - private isValidImageChangedEvent(): boolean { - return this.imageChangedEvent?.target?.files?.length > 0; + private isValidImageChangedEvent(): this is { + imageChangedEvent: Event & { + target: { files: FileList }; + } + } { + const files = (this.imageChangedEvent as any)?.target?.files; + return files instanceof FileList && files.length > 0; } private setCssTransform() { @@ -267,7 +273,7 @@ export class ImageCropperComponent implements OnChanges, OnInit { this.cd.markForCheck(); } - public loadImageError(error: any): void { + public loadImageError(error: unknown): void { console.error(error); this.loadImageFailed.emit(); } @@ -360,7 +366,7 @@ export class ImageCropperComponent implements OnChanges, OnInit { } } - private keyboardMoveCropper(event: any) { + private keyboardMoveCropper(event: KeyboardEvent) { const keyboardWhiteList: string[] = ['ArrowUp', 'ArrowDown', 'ArrowRight', 'ArrowLeft']; if (!(keyboardWhiteList.includes(event.key))) { return; @@ -375,13 +381,13 @@ export class ImageCropperComponent implements OnChanges, OnInit { this.handleMouseUp(); } - startMove(event: any, moveType: MoveTypes, position: string | null = null): void { + startMove(event: Event | BasicEvent, moveType: MoveTypes, position: string | null = null): void { if (this.disabled || this.moveStart?.active && this.moveStart?.type === MoveTypes.Pinch || moveType === MoveTypes.Drag && !this.allowMoveImage) { return; } - if (event.preventDefault) { + if ('preventDefault' in event) { event.preventDefault(); } this.moveStart = { @@ -435,12 +441,12 @@ export class ImageCropperComponent implements OnChanges, OnInit { }; } - private handleMouseMove(event: any): void { + private handleMouseMove(event: Event | BasicEvent): void { if (this.moveStart!.active) { - if (event.stopPropagation) { + if ('stopPropagation' in event) { event.stopPropagation(); } - if (event.preventDefault) { + if ('preventDefault' in event) { event.preventDefault(); } if (this.moveStart!.type === MoveTypes.Move) { diff --git a/projects/ngx-image-cropper/src/lib/interfaces/basic-event.interface.ts b/projects/ngx-image-cropper/src/lib/interfaces/basic-event.interface.ts new file mode 100644 index 0000000..d3d711a --- /dev/null +++ b/projects/ngx-image-cropper/src/lib/interfaces/basic-event.interface.ts @@ -0,0 +1,4 @@ +export interface BasicEvent { + clientX: number; + clientY: number; +} diff --git a/projects/ngx-image-cropper/src/lib/services/cropper-position.service.ts b/projects/ngx-image-cropper/src/lib/services/cropper-position.service.ts index bca67bb..c44ece4 100644 --- a/projects/ngx-image-cropper/src/lib/services/cropper-position.service.ts +++ b/projects/ngx-image-cropper/src/lib/services/cropper-position.service.ts @@ -1,6 +1,7 @@ import { ElementRef, Injectable } from '@angular/core'; import { CropperPosition, Dimensions, MoveStart } from '../interfaces'; import { CropperSettings } from '../interfaces/cropper.settings'; +import {BasicEvent} from "../interfaces/basic-event.interface"; @Injectable({ providedIn: 'root' }) export class CropperPositionService { @@ -40,7 +41,7 @@ export class CropperPositionService { } } - move(event: any, moveStart: MoveStart, cropperPosition: CropperPosition) { + move(event: Event | BasicEvent, moveStart: MoveStart, cropperPosition: CropperPosition) { const diffX = this.getClientX(event) - moveStart.clientX; const diffY = this.getClientY(event) - moveStart.clientY; @@ -50,7 +51,7 @@ export class CropperPositionService { cropperPosition.y2 = moveStart.y2 + diffY; } - resize(event: any, moveStart: MoveStart, cropperPosition: CropperPosition, maxSize: Dimensions, settings: CropperSettings): void { + resize(event: Event | BasicEvent, moveStart: MoveStart, cropperPosition: CropperPosition, maxSize: Dimensions, settings: CropperSettings): void { const moveX = this.getClientX(event) - moveStart.clientX; const moveY = this.getClientY(event) - moveStart.clientY; switch (moveStart.position) { @@ -95,7 +96,7 @@ export class CropperPositionService { cropperPosition.y1 + settings.cropperScaledMinHeight); break; case 'center': - const scale = event.scale; + const scale = (event as any).scale; const newWidth = Math.min( Math.max(settings.cropperScaledMinWidth, (Math.abs(moveStart.x2 - moveStart.x1)) * scale), settings.cropperScaledMaxWidth); @@ -206,11 +207,23 @@ export class CropperPositionService { } } - getClientX(event: any): number { - return event.touches?.[0].clientX || event.clientX || 0; + getClientX(event: Event | BasicEvent | TouchEvent): number { + if ('touches' in event && event.touches[0]) + return event.touches[0].clientX; + else if ('clientX' in event) { + return event.clientX + } + + return 0; } - getClientY(event: any): number { - return event.touches?.[0].clientY || event.clientY || 0; + getClientY(event: Event | BasicEvent | TouchEvent): number { + if ('touches' in event && event.touches[0]) + return event.touches[0].clientY; + else if ('clientX' in event) { + return event.clientY + } + + return 0; } } diff --git a/projects/ngx-image-cropper/src/lib/utils/keyboard.utils.ts b/projects/ngx-image-cropper/src/lib/utils/keyboard.utils.ts index c00b0fb..bd72ea1 100644 --- a/projects/ngx-image-cropper/src/lib/utils/keyboard.utils.ts +++ b/projects/ngx-image-cropper/src/lib/utils/keyboard.utils.ts @@ -1,3 +1,5 @@ +import {BasicEvent} from "../interfaces/basic-event.interface"; + export function getPositionForKey(key: string): string { switch (key) { case 'ArrowUp': @@ -26,7 +28,7 @@ export function getInvertedPositionForKey(key: string): string { } } -export function getEventForKey(key: string, stepSize: number): any { +export function getEventForKey(key: string, stepSize: number): BasicEvent { switch (key) { case 'ArrowUp': return {clientX: 0, clientY: stepSize * -1};