diff --git a/biome.json b/biome.json index ca5f101..089d265 100644 --- a/biome.json +++ b/biome.json @@ -19,10 +19,7 @@ "linter": { "enabled": true, "rules": { - "recommended": true, - "suspicious": { - "noExplicitAny": "off" - } + "recommended": true } }, "javascript": { diff --git a/src/main.ts b/src/main.ts index e09a1a1..464c853 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,6 +1,6 @@ interface CustomElement extends HTMLElement { - setState(key_path: string, value: any): void - getState(key_path: string): any + setState(key_path: string, value: unknown): void + getState(key_path: string): unknown } interface ComponentOptions { @@ -14,9 +14,9 @@ interface ComponentOptions { oldValue: string, newValue: string, ) => void - states?: Record - statesListeners?: { [key: string]: (value: any) => void } - funcs?: { [key: string]: (...args: any[]) => void } + states?: Record + statesListeners?: { [key: string]: (value: unknown) => void } + funcs?: { [key: string]: (...args: unknown[]) => void } } export default (options: ComponentOptions) => { @@ -35,10 +35,10 @@ export default (options: ComponentOptions) => { componentRegistry.set(tag, options) class CustomElementImpl extends HTMLElement { - private _states: Record = {} + private _states: Record = {} private _stateToElementsMap: Record> = {} private _currentRenderingElement: HTMLElement | null = null - private _statesListeners: Record void> = {} + private _statesListeners: Record void> = {} private _textBindings: Array<{ node: Text expr: string @@ -66,7 +66,7 @@ export default (options: ComponentOptions) => { this._states = new Proxy( { ...(states || {}) }, { - set: (target: Record, keyPath: string, value: any) => { + set: (target: Record, keyPath: string, value: unknown) => { const valueRoute = keyPath.split('.') let currentTarget = target for (const i in valueRoute) { @@ -74,10 +74,9 @@ export default (options: ComponentOptions) => { if (Number.parseInt(i) === valueRoute.length - 1) { currentTarget[key] = value } else { - if (!currentTarget[key]) { + if (!currentTarget[key]) currentTarget[key] = {} - } - currentTarget = currentTarget[key] + currentTarget = currentTarget[key] as Record } } // trigger dom updates @@ -97,7 +96,7 @@ export default (options: ComponentOptions) => { return true }, - get: (target: Record, keyPath: string) => { + get: (target: Record, keyPath: string) => { // collect state dependencies if (this._currentRenderingElement) { if (!this._stateToElementsMap[keyPath]) @@ -116,7 +115,7 @@ export default (options: ComponentOptions) => { if (!currentTarget[key]) currentTarget[key] = {} - currentTarget = currentTarget[key] + currentTarget = currentTarget[key] as Record } return undefined }, @@ -205,7 +204,7 @@ export default (options: ComponentOptions) => { } private _updateElement(element: HTMLElement) { - const renderFunction = (element as any)._renderFunction + const renderFunction = (element as { _renderFunction?: () => string | Node })._renderFunction if (renderFunction) { // Set rendering context this._currentRenderingElement = element @@ -350,11 +349,11 @@ export default (options: ComponentOptions) => { eventName, handlerValue, ) - } else if (typeof (this as any)[handlerValue] === 'function') { + } else if (typeof (this as Record)[handlerValue] === 'function') { // Handle method reference: @click="handleClick" currentElementNode.addEventListener( eventName, - (this as any)[handlerValue].bind(this), + ((this as unknown as Record void>)[handlerValue]).bind(this), ) } else { // Handle simple expression: @click="count++" or @input="name = $event.target.value" @@ -425,12 +424,11 @@ export default (options: ComponentOptions) => { }) // Add event listener for state changes - this._statesListeners[expr] = (newValue: any) => { - if (element instanceof HTMLInputElement) { - element.value = newValue - } else { + this._statesListeners[expr] = (newValue: unknown) => { + if (element instanceof HTMLInputElement) + element.value = newValue as string + else element.setAttribute('data-laterano-connect', String(newValue)) - } } } @@ -482,8 +480,8 @@ export default (options: ComponentOptions) => { // Store current rendered items const renderedItems: Array<{ element: Element - key: any - data: any + key: unknown + data: unknown index: number }> = [] @@ -620,10 +618,10 @@ export default (options: ComponentOptions) => { // Recursively process the element and its children, applying the item context private _processElementWithItemContext( element: Element, - itemContext: Record, + itemContext: Record, ) { // 1. Store the item context of the element so that subsequent updates can find it - ; (element as any)._itemContext = itemContext + ; (element as { _itemContext?: Record })._itemContext = itemContext // 2. Process bindings in text nodes const processTextNodes = (node: Node) => { @@ -768,7 +766,7 @@ export default (options: ComponentOptions) => { private _setupNestedListRendering( element: Element, expr: string, - parentItemContext: Record, + parentItemContext: Record, ) { // Similar to _setupListRendering, but applies to nested situations // Parse the expression (e.g., "subItem in item.subItems") @@ -837,11 +835,11 @@ export default (options: ComponentOptions) => { // Evaluate expressions using the item context private _evaluateExpressionWithItemContext( expression: string, - itemContext: Record, + itemContext: Record, index?: number, itemVar?: string, indexVar?: string, - ): any { + ): unknown { try { // Check if the expression directly references the item variable if (itemVar && expression === itemVar) { @@ -857,7 +855,7 @@ export default (options: ComponentOptions) => { for (const part of parts) { if (value === undefined || value === null) return undefined - value = value[part] + value = (value as { [key: string]: unknown})[part] } return value @@ -911,7 +909,7 @@ export default (options: ComponentOptions) => { } } - private _evaluateExpression(expression: string): any { + private _evaluateExpression(expression: string): unknown { try { // get the state keys and values if (this._states[expression] !== undefined) @@ -1012,12 +1010,12 @@ export default (options: ComponentOptions) => { private _createHandlerContext(event: Event, element: Element) { // Basic context, including state const context: { - [key: string]: any + [key: string]: unknown $event: Event $el: Element this: CustomElementImpl // Provide reference to the component instance - setState: (keyPath: string, value: any) => void - getState: (keyPath: string) => any + setState: (keyPath: string, value: unknown) => void + getState: (keyPath: string) => unknown } = { ...this._states, $event: event, @@ -1032,10 +1030,10 @@ export default (options: ComponentOptions) => { // (name) => { for (const name of Object.getOwnPropertyNames(Object.getPrototypeOf(this))) if ( - typeof (this as any)[name] === 'function' && + typeof (this as Record)[name] === 'function' && name !== 'constructor' ) - context[name] = (this as any)[name].bind(this) + context[name] = (this as unknown as Record void>)[name].bind(this) return context } @@ -1147,16 +1145,15 @@ export default (options: ComponentOptions) => { } // Get nested state value - private _getNestedState(path: string): any { + private _getNestedState(path: string): unknown { // Handle nested paths, such as "profile.name" const parts = path.split('.') let result = this._states for (const part of parts) { - if (result === undefined || result === null) { + if (result === undefined || result === null) return undefined - } - result = result[part] + result = (result as { [key: string]: Record })[part] } return result @@ -1183,23 +1180,23 @@ export default (options: ComponentOptions) => { } // state manager - setState(keyPath: string, value: any) { + setState(keyPath: string, value: unknown) { this._states[keyPath] = value } - getState(keyPath: string): any { + getState(keyPath: string): unknown { const parts = keyPath.split('.') let result = this._states for (const part of parts) { if (result === undefined || result === null) return undefined - result = result[part] + result = (result as { [key: string]: Record })[part] } return result } // function trigger - triggerFunc(eventName: string, ...args: any[]) { + triggerFunc(eventName: string, ...args: unknown[]) { funcs?.[eventName]?.call(this, ...args) } }