diff --git a/packages/shared/src/components/containers/InfiniteScrolling.tsx b/packages/shared/src/components/containers/InfiniteScrolling.tsx index ffbc3e21b8..3775b9e5bb 100644 --- a/packages/shared/src/components/containers/InfiniteScrolling.tsx +++ b/packages/shared/src/components/containers/InfiniteScrolling.tsx @@ -22,10 +22,8 @@ export type InfiniteScrollingQueryProps = Pick< 'canFetchMore' | 'isFetchingNextPage' | 'fetchNextPage' | 'placeholder' >; -export const checkFetchMore = ( - // (Specific since we don't know inferred type) - // eslint-disable-next-line @typescript-eslint/no-explicit-any - queryResult: UseInfiniteQueryResult>, +export const checkFetchMore = ( + queryResult: UseInfiniteQueryResult>, ): boolean => !queryResult.isLoading && !queryResult.isFetchingNextPage && diff --git a/packages/shared/src/components/feeds/FeedSettings/types.ts b/packages/shared/src/components/feeds/FeedSettings/types.ts index 0ab6da3edd..a0379c6925 100644 --- a/packages/shared/src/components/feeds/FeedSettings/types.ts +++ b/packages/shared/src/components/feeds/FeedSettings/types.ts @@ -25,10 +25,7 @@ export type FeedSettingsEditContextValue = { onDiscard: ({ activeView }?: { activeView?: string }) => Promise; isDirty: boolean; onBackToFeed: ({ action }: { action: 'discard' | 'save' }) => void; - // eslint-disable-next-line @typescript-eslint/no-explicit-any - editFeedSettings: any>( - callback?: T, - ) => ReturnType; + editFeedSettings: (callback?: () => TResult) => TResult | undefined; isNewFeed: boolean; }; diff --git a/packages/shared/src/components/modals/ShareModal.tsx b/packages/shared/src/components/modals/ShareModal.tsx index 3351dec41e..1c7afe4468 100644 --- a/packages/shared/src/components/modals/ShareModal.tsx +++ b/packages/shared/src/components/modals/ShareModal.tsx @@ -1,6 +1,7 @@ import type { ReactElement } from 'react'; import React, { useContext, useEffect, useState } from 'react'; import { useSwipeable } from 'react-swipeable'; +import type { SwipeEventData } from 'react-swipeable'; import { SocialShare } from '../widgets/SocialShare'; import { useLogContext } from '../../contexts/LogContext'; import { postLogEvent } from '../../lib/feed'; @@ -52,12 +53,17 @@ export default function ShareModal({ // eslint-disable-next-line react-hooks/exhaustive-deps }, []); - // eslint-disable-next-line @typescript-eslint/no-explicit-any - const onSwipedDown = (e: any) => { - const { scrollTop } = e.event.currentTarget; + const onSwipedDown = (e: SwipeEventData) => { + const currentTarget = e.event.currentTarget as HTMLElement | null; + + if (!currentTarget) { + return; + } + + const { scrollTop } = currentTarget; if (scrollTop === 0) { - onRequestClose(e); + onRequestClose(e.event as React.MouseEvent); } }; diff --git a/packages/shared/src/graphql/types.ts b/packages/shared/src/graphql/types.ts index 87a6d59c70..7f590e8af7 100644 --- a/packages/shared/src/graphql/types.ts +++ b/packages/shared/src/graphql/types.ts @@ -1,7 +1,6 @@ declare module 'graphql-request/dist/types' { interface GraphQLError { - // eslint-disable-next-line @typescript-eslint/no-explicit-any - extensions?: Record; + extensions?: Record; message?: string; } } diff --git a/packages/shared/src/hooks/useEventListener.ts b/packages/shared/src/hooks/useEventListener.ts index 6aef740199..fc7ab612cb 100644 --- a/packages/shared/src/hooks/useEventListener.ts +++ b/packages/shared/src/hooks/useEventListener.ts @@ -61,8 +61,7 @@ export type DOMEventMapDefinitions = [ ]; type MapDefinitionToEventMap = { - // eslint-disable-next-line @typescript-eslint/no-explicit-any - [K in keyof D]: D[K] extends [any, any] + [K in keyof D]: D[K] extends [unknown, unknown] ? T extends D[K][0] ? D[K][1] : never @@ -94,6 +93,17 @@ export interface MessageEventData { eventKey?: string; } +type DOMEvent< + T, + K extends string, + M extends GetDOMEventMaps, +> = MapEventMapsToEvent[number]; + +const isRefObject = ( + value: RefObject | T | null | undefined, +): value is RefObject => + typeof value === 'object' && value !== null && 'current' in value; + const useEventListener = < T extends EventTarget, K extends MapEventMapsToKeys[number] & string, @@ -101,47 +111,46 @@ const useEventListener = < >( target: RefObject | T | null | undefined, eventType: K, - listener: GenericEventListener[number]>, + listener: GenericEventListener>, options?: TUseEventListenerOptions, ): void => { - // eslint-disable-next-line @typescript-eslint/no-explicit-any - const handlerRef = useRef(listener); + const handlerRef = useRef(listener); handlerRef.current = listener; const { once, passive, signal }: AddEventListenerOptions = typeof options === 'object' ? options : {}; - let eventOptions: boolean | AddEventListenerOptions | undefined = - useMemo(() => { - const computedOptions: AddEventListenerOptions = {}; + const booleanOptions = typeof options === 'boolean' ? options : undefined; - if (once !== undefined) { - computedOptions.once = once; - } + const eventOptions = useMemo(() => { + if (booleanOptions !== undefined) { + return booleanOptions; + } - if (passive !== undefined) { - computedOptions.passive = passive; - } + const computedOptions: AddEventListenerOptions = {}; - if (signal !== undefined) { - computedOptions.signal = signal; - } + if (once !== undefined) { + computedOptions.once = once; + } - return Object.keys(computedOptions).length > 0 - ? computedOptions - : undefined; - }, [once, passive, signal]); + if (passive !== undefined) { + computedOptions.passive = passive; + } + + if (signal !== undefined) { + computedOptions.signal = signal; + } - if (typeof options === 'boolean') { - eventOptions = options; - } + return Object.keys(computedOptions).length > 0 + ? computedOptions + : undefined; + }, [booleanOptions, once, passive, signal]); useEffect(() => { - const eventListener = (...args) => { - return handlerRef.current(...args); + const eventListener: EventListener = (event) => { + handlerRef.current(event as DOMEvent); }; - const targetElement = - target && 'current' in target ? target.current : (target as T); + const targetElement = isRefObject(target) ? target.current : target; if (targetElement && eventType && eventListener) { targetElement.addEventListener(eventType, eventListener, eventOptions); diff --git a/packages/shared/src/lib/auth.ts b/packages/shared/src/lib/auth.ts index 447ca7a126..0b3013c79f 100644 --- a/packages/shared/src/lib/auth.ts +++ b/packages/shared/src/lib/auth.ts @@ -217,10 +217,10 @@ export type NativeAuthResponse = { export const iosNativeAuth = async ( provider: string, ): Promise => { - const promise = promisifyEventListener( - 'native-auth', - (event) => event.detail, - ); + const promise = promisifyEventListener< + NativeAuthResponse | undefined, + NativeAuthResponse | undefined + >('native-auth', (event) => event.detail); postWebKitMessage(WebKitMessageHandlers.NativeAuth, provider); return promise; }; diff --git a/packages/shared/src/lib/form.ts b/packages/shared/src/lib/form.ts index 93728701ef..15927fbb43 100644 --- a/packages/shared/src/lib/form.ts +++ b/packages/shared/src/lib/form.ts @@ -1,4 +1,4 @@ -import type { UseFormSetError } from 'react-hook-form'; +import type { FieldValues, Path, UseFormSetError } from 'react-hook-form'; import type { GraphQLError } from './errors'; import type { ApiResponseError, ApiZodErrorExtension } from '../graphql/common'; import { ApiError } from '../graphql/common'; @@ -71,13 +71,12 @@ export function formToJson>( return values as unknown as T; } -export const applyZodErrorsToForm = ({ +export const applyZodErrorsToForm = ({ error: originalError, setError, }: { error: GraphQLError; - // eslint-disable-next-line @typescript-eslint/no-explicit-any - setError: UseFormSetError; + setError: UseFormSetError; }) => { if ( originalError.response?.errors?.[0]?.extensions?.code === @@ -88,7 +87,7 @@ export const applyZodErrorsToForm = ({ apiError.extensions.issues.forEach((issue) => { if (issue.path?.length) { - setError(issue.path.join('.'), { + setError(issue.path.join('.') as Path, { type: issue.code, message: issue.message, }); diff --git a/packages/shared/src/lib/func.ts b/packages/shared/src/lib/func.ts index 7217697788..4b7acb7976 100644 --- a/packages/shared/src/lib/func.ts +++ b/packages/shared/src/lib/func.ts @@ -229,8 +229,7 @@ export const broadcastMessage = ( channel.close(); }; -// eslint-disable-next-line @typescript-eslint/no-explicit-any -export const promisifyEventListener = ( +export const promisifyEventListener = ( type: string, listener: (event: CustomEvent) => T | Promise, options?: { once?: boolean },