diff --git a/.changeset/eight-birds-invite.md b/.changeset/eight-birds-invite.md new file mode 100644 index 0000000000..7e3351cd3e --- /dev/null +++ b/.changeset/eight-birds-invite.md @@ -0,0 +1,6 @@ +--- +'@rocket.chat/fuselage-hooks': patch +'@rocket.chat/fuselage': patch +--- + +fix(fuselage-hooks): Stricter generics for `useEffectEvent` diff --git a/packages/fuselage-hooks/src/useEffectEvent.ts b/packages/fuselage-hooks/src/useEffectEvent.ts index bbe9f8a1b9..077db35a6f 100644 --- a/packages/fuselage-hooks/src/useEffectEvent.ts +++ b/packages/fuselage-hooks/src/useEffectEvent.ts @@ -13,10 +13,14 @@ import { useIsomorphicLayoutEffect } from './useIsomorphicLayoutEffect'; * @returns a stable callback * @public */ -export const useEffectEvent =

( - fn: (...args: P) => T, -): ((...args: P) => T) => { +export const useEffectEvent = ( + fn: TFunction, +) => { const fnRef = useRef(fn); + + type P = TFunction extends (...args: infer P) => any ? P : never; + type T = TFunction extends (...args: any) => infer T ? T : never; + const stableFnRef = useRef( (...args: P): T => fnRef.current.call(undefined, ...args), ); diff --git a/packages/fuselage/src/components/PaginatedSelect/PaginatedSelect.tsx b/packages/fuselage/src/components/PaginatedSelect/PaginatedSelect.tsx index c2cf23286a..09fa71fa05 100644 --- a/packages/fuselage/src/components/PaginatedSelect/PaginatedSelect.tsx +++ b/packages/fuselage/src/components/PaginatedSelect/PaginatedSelect.tsx @@ -1,7 +1,7 @@ import { useEffectEvent, useResizeObserver } from '@rocket.chat/fuselage-hooks'; import { type ElementType, useState, useRef, useMemo } from 'react'; -import { type SelectProps } from '..'; +import { OptionType, SelectOption, type SelectProps } from '..'; import { prevent } from '../../helpers/prevent'; import AnimatedVisibility from '../AnimatedVisibility'; import Box from '../Box'; @@ -52,9 +52,9 @@ export const PaginatedSelect = ({ const [visible, hide, show] = useVisible(); - const internalChangedByClick = useEffectEvent(([value]) => { + const internalChangedByClick = useEffectEvent(([value]: OptionType) => { setInternalValue(value); - onChange(value); + onChange(value as SelectOption[0]); // FIXME hide(); }); diff --git a/packages/fuselage/src/components/Select/SelectLegacy.tsx b/packages/fuselage/src/components/Select/SelectLegacy.tsx index 2f1e8b3c92..26ba243378 100644 --- a/packages/fuselage/src/components/Select/SelectLegacy.tsx +++ b/packages/fuselage/src/components/Select/SelectLegacy.tsx @@ -89,9 +89,9 @@ export const SelectLegacy = forwardRef( ) => { const [internalValue, setInternalValue] = useState(value || ''); - const internalChangedByKeyboard = useEffectEvent(([value]) => { + const internalChangedByKeyboard = useEffectEvent(([value]: OptionType) => { setInternalValue(value); - onChange(value); + onChange(value as SelectOption[0]); // FIXME }); const option = options.find( @@ -123,9 +123,9 @@ export const SelectLegacy = forwardRef( const removeFocusClass = () => innerRef.current?.classList.remove('focus-visible'); - const internalChangedByClick = useEffectEvent(([value]) => { + const internalChangedByClick = useEffectEvent(([value]: OptionType) => { setInternalValue(value); - onChange(value); + onChange(value as SelectOption[0]); // FIXME removeFocusClass(); hide(); });