From d8bdc2dcfa3a9c4d9c596ce88c768089f630707c Mon Sep 17 00:00:00 2001 From: Buddy Date: Tue, 9 Jun 2026 21:06:58 -0700 Subject: [PATCH] refactor: replace any with generics in NumProp and BoolOffProp Make NumProp and BoolOffProp generic (NumProp, BoolOffProp) instead of using any, with T inferred from callback parameters at call sites via the num() and off() factory helpers. Remove unused num import from leaflet-tile-layer-wms. Fix prettier formatting issues. --- src/components/leaflet-map.ts | 8 +++- src/components/leaflet-tile-layer-wms.ts | 7 +-- src/core/path-style.ts | 2 +- src/core/props.ts | 56 ++++++++++++++---------- 4 files changed, 41 insertions(+), 32 deletions(-) diff --git a/src/components/leaflet-map.ts b/src/components/leaflet-map.ts index 7a18920..f4002d1 100644 --- a/src/components/leaflet-map.ts +++ b/src/components/leaflet-map.ts @@ -55,10 +55,14 @@ const PROPS = defineProps({ transform3DLimit: num(8388608), // Boolean defaults-true → disable-* attribute; handler-based options have live mapSet - scrollWheelZoom: off((m: LMap, v: boolean) => (v ? m.scrollWheelZoom.enable() : m.scrollWheelZoom.disable())), + scrollWheelZoom: off((m: LMap, v: boolean) => + v ? m.scrollWheelZoom.enable() : m.scrollWheelZoom.disable(), + ), dragging: off((m: LMap, v: boolean) => (v ? m.dragging.enable() : m.dragging.disable())), touchZoom: off((m: LMap, v: boolean) => (v ? m.touchZoom.enable() : m.touchZoom.disable())), - doubleClickZoom: off((m: LMap, v: boolean) => (v ? m.doubleClickZoom.enable() : m.doubleClickZoom.disable())), + doubleClickZoom: off((m: LMap, v: boolean) => + v ? m.doubleClickZoom.enable() : m.doubleClickZoom.disable(), + ), boxZoom: off((m: LMap, v: boolean) => (v ? m.boxZoom.enable() : m.boxZoom.disable())), keyboard: off((m: LMap, v: boolean) => (v ? m.keyboard.enable() : m.keyboard.disable())), closePopupOnClick: off(), diff --git a/src/components/leaflet-tile-layer-wms.ts b/src/components/leaflet-tile-layer-wms.ts index b3822e5..54c069a 100644 --- a/src/components/leaflet-tile-layer-wms.ts +++ b/src/components/leaflet-tile-layer-wms.ts @@ -3,7 +3,7 @@ import { buildOptions, buildAttrMap, setLayerAttr, parseAttributeValue } from '. import { WithProps } from '../core/with-props.ts'; import { registerChildren, unregisterChildren } from '../core/register.ts'; -import { defineProps, num, str, on } from '../core/props.ts'; +import { defineProps, str, on } from '../core/props.ts'; const PROPS = defineProps({ url: str(), @@ -22,10 +22,7 @@ export default class LeafletTileLayerWMS extends WithProps(HTMLElement, PROPS) { connectedCallback() { const url = this.getAttribute('url') || ''; - this.#obj = new TileLayer.WMS( - url, - buildOptions(this, PROPS, ['url']), - ); + this.#obj = new TileLayer.WMS(url, buildOptions(this, PROPS, ['url'])); registerChildren(this, this.#obj); } diff --git a/src/core/path-style.ts b/src/core/path-style.ts index 2e3fac9..09d0827 100644 --- a/src/core/path-style.ts +++ b/src/core/path-style.ts @@ -2,7 +2,7 @@ import { Path } from 'leaflet'; import { parseAttributeValue } from './utils.ts'; // The set of HTML attribute names that map to Leaflet Path style options. -// These are handled specially because Leaflet exposes them through +// These are handled especially because Leaflet exposes them through // setStyle() rather than individual setter methods, and they are shared // across many vector components (polyline, polygon, circle, rectangle). const PATH_STYLE_ATTRS = new Set([ diff --git a/src/core/props.ts b/src/core/props.ts index 61c77b9..b59aee1 100644 --- a/src/core/props.ts +++ b/src/core/props.ts @@ -1,9 +1,9 @@ -export type NumProp = { +export type NumProp = { kind: 'num'; attr: string; default: number; - mapGet?: (m: any) => number | undefined; - mapSet?: (m: any, v: number) => void; + mapGet?: (m: T) => number | undefined; + mapSet?: (m: T, v: number) => void; viewState?: boolean; event?: string; }; @@ -19,13 +19,13 @@ export type BoolOnProp = { attr: string; }; -export type BoolOffProp = { +export type BoolOffProp = { kind: 'bool-off'; attr: string; - mapSet?: (m: any, enabled: boolean) => void; + mapSet?: (m: T, enabled: boolean) => void; }; -export type PropDef = NumProp | StrProp | BoolOnProp | BoolOffProp; +export type PropDef = NumProp | StrProp | BoolOnProp | BoolOffProp; export type PropTypeOf = T extends NumProp ? number @@ -41,29 +41,36 @@ export type PropTypesFromTable> = { type OptionalAttr = Omit & { attr?: string }; -type NumPropInput = OptionalAttr; +type NumPropInput = OptionalAttr>; type StrPropInput = OptionalAttr; type BoolOnPropInput = OptionalAttr; -type BoolOffPropInput = OptionalAttr; +type BoolOffPropInput = OptionalAttr>; -type PropDefInput = NumPropInput | StrPropInput | BoolOnPropInput | BoolOffPropInput; +type PropDefInput = + | NumPropInput + | StrPropInput + | BoolOnPropInput + | BoolOffPropInput; type PropDefFromInput = - T extends { kind: 'num' } ? NumProp - : T extends { kind: 'str' } ? StrProp - : T extends { kind: 'bool-off' } ? BoolOffProp - : BoolOnProp; + T extends NumPropInput + ? NumProp + : T extends { kind: 'str' } + ? StrProp + : T extends BoolOffPropInput + ? BoolOffProp + : BoolOnProp; function camelToKebab(s: string): string { - return s.replace(/[A-Z]/g, c => '-' + c.toLowerCase()); + return s.replace(/[A-Z]/g, (c) => '-' + c.toLowerCase()); } -export function num( +export function num( def: number = 0, - opts?: string | (Omit & { attr?: string }), -): NumPropInput { + opts?: string | (Omit, 'kind' | 'default' | 'attr'> & { attr?: string }), +): NumPropInput { if (typeof opts === 'string') opts = { attr: opts }; - return { kind: 'num', default: def, ...opts }; + return { kind: 'num', default: def, ...opts } as NumPropInput; } export function str(def: string = '', attr?: string): StrPropInput { @@ -74,19 +81,20 @@ export function on(attr?: string): BoolOnPropInput { return { kind: 'bool-on', ...(attr ? { attr } : {}) }; } -export function off(mapSet?: (m: any, enabled: boolean) => void): BoolOffPropInput { - return { kind: 'bool-off', ...(mapSet ? { mapSet } : {}) }; +export function off(mapSet?: (m: T, enabled: boolean) => void): BoolOffPropInput { + return { kind: 'bool-off', ...(mapSet ? { mapSet } : {}) } as BoolOffPropInput; } -export function defineProps>( +export function defineProps>( input: T, ): { [K in keyof T]: PropDefFromInput } { const output = {} as Record; for (const key of Object.keys(input)) { const val = input[key] as PropDefInput; - const { attr: override, ...rest } = val as any; - const attr = override ?? (rest.kind === 'bool-off' ? 'disable-' + camelToKebab(key) : camelToKebab(key)); + const { attr: override, ...rest } = val as unknown as Record; + const attr = + override ?? (rest.kind === 'bool-off' ? 'disable-' + camelToKebab(key) : camelToKebab(key)); output[key] = { ...rest, attr } as PropDef; } - return output as any; + return output as unknown as { [K in keyof T]: PropDefFromInput }; }