modern-agile-team / modern-kit

@modern-kit은 클라이언트 개발에 유용한 모듈들을 제공하는 오픈소스 라이브러리 입니다.
https://modern-agile-team.github.io/modern-kit/
MIT License
84 stars 11 forks source link

[BUG]:useThrottle #586

Open rhehfl opened 5 hours ago

rhehfl commented 5 hours ago

Package Scope


버그 요약 설명


예상되는 동작


재현 코드 혹은 설명


가능한 해결책

export function useThrottle<T extends ThrottleParameters[0]>(
  callback: T,
  wait: ThrottleParameters[1],
  options: ThrottleParameters[2] = {}
): ThrottleReturnType<T> {
  const callbackAction = usePreservedCallback(callback);
  const preservedOptions = usePreservedState(options);

  // useMemo에 제네릭을 명시하여 throttled의 타입을 정확하게 추론하도록 합니다.
  const throttled = useMemo<ThrottleReturnType<T>>(() => {
    return throttle(callbackAction, wait, preservedOptions);
  }, [callbackAction, wait, preservedOptions]);

  // 언마운트 시 쓰로틀 된 함수의 보류 중인 호출을 모두 버립니다.
  useUnmount(() => throttled.cancel());

  return throttled;
}
ssi02014 commented 3 hours ago

@rhehfl 저의 경우에는 제대로 타입 추론이 되고 있는 상황인데요.

사례

스크린샷 2024-11-18 오전 12 21 19

ThrottleReturnType

스크린샷 2024-11-18 오전 12 23 17


제가 확인해봤을 때 현재 lodash-es가 사용자 측에 의존성으로 설치되어 있지 않을 경우 타입 추론이 제대로 되지 않는 다는 것입니다. 저의 경우에도 lodash-es가 없는 상태에서 modern-kit을 사용할 경우 이슈가 발생하네요.

이 경우에는 예상하기로는 lodash-es가 현재 devDependencies 포함되어 있기 때문입니다.


PR: https://github.com/modern-agile-team/modern-kit/pull/587 해당 PR에서 lodash-es의 위치를 dependencies 로 변경하였습니다. 이 변경 사항은 modern-kit/react v1.24.0 에 포함 될 예정입니다. 배포하게 되면 다시한번 확인해주시면 감사드립니다.

ssi02014 commented 2 hours ago

devDependencies 에서 dependencies lodash-es를 옮겼음에도 현상이 동일해 @types/lodash-es도 dependencies에 포함하도록 변경 하였습니다.

ssi02014 commented 2 hours ago

@rhehfl @modern-kit/react v1.24.1 해당 문제가 해결된 것으로 보입니다 :) 한번 확인해주시면 감사드립니다.

해당 현상에 대해 정리해보자면,

  1. 현재 modern-kit/react를 빌드 시에 lodash-esthrottle 타입이 빌드 시 d.ts 파일에 직접 정의되지 않고 import를 합니다.
    
    // dist/hooks/useThrottle/index.d.ts
    import { throttle } from 'lodash-es'; // (*) 이 부분입니다.
    export type ThrottleParameters = Parameters<typeof throttle>;
    export type ThrottleReturnType<T extends ThrottleParameters[0]> = ReturnType<typeof throttle<T>>;

// ... export declare function useThrottle<T extends ThrottleParameters[0]>(callback: T, wait: ThrottleParameters[1], options?: ThrottleParameters[2]): ThrottleReturnType;



<img width="1072" alt="스크린샷 2024-11-18 오전 2 00 54" src="https://github.com/user-attachments/assets/766aca50-e174-4e9b-8392-4aef926d8eb2">

<br />

위 이미지처럼 `@types/lodash-es`를 바라보는 것을 확인 할 수 있습니다.

2. 위와 같은 현상은 근본적으로 `lodash-es`측에서 직접적으로 `타입스크립트를 지원하지 않기때문에` 발생하는 것으로 보입니다. 직접 제공하는 것 대신 `@types/lodash-es` 라는 별도의 의존성을 설치해서 타입을 지원합니다.
- 즉, lodash-es는 `.ts` 파일로 구성되어 있지 않습니다. lodash-es가 `@types/lodash-es`아닌 `직접 타입을 제공`해주면 좋겠지만 외부 라이브러리이기 때문에 우리가 제어하기는 힘들고, lodash 측에서 타입 제공을 위한 작업(노오력)을 해줘야합니다.
  - 참고: https://github.com/lodash/lodash/tree/4.17.21-es 
- `@types/lodash-es`는 [DefinitelyTyped](https://github.com/DefinitelyTyped/DefinitelyTyped) 라는 외부 패키지를 통해 제공합니다. (`@types/*` 관련 타입 패키지는 모두 여기서 제공)
  - 참고1: https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/lodash-es
  - 참고2: https://www.npmjs.com/package/@types/lodash-es
3. 다시 @modern-kit으로 돌아와 기존에는 `@types/lodash-es`는 기존에 `devDependencies` 포함되어 있었기 때문에 사용자가 @modern-kit/react를 설치 시에 @types/lodash-es 의존성을 설치하지 않습니다. 
- `devDependencies` 는 개발 단계에서만 필요한 라이브러리를 명시합니다. 여기에 명시된 패키지는 `배포 시 포함되지 않습니다.` 즉, @modern-kit/react를 외부에서 설치 시 devDependencies에 명시된 패키지는 설치되지 않습니다.
- 예를 들어, devDependencies에는 `eslint`, `prettier` 등이 포함 될 수 있습니다.
4. 위에 설명드린 이유로 사용자 측에서 프로젝트 내 `@types/lodash-es` 를 설치하지 않는다면 제대로된 타입 추론을 못한다는 이슈가 발생합니다.
6. 따라서, @modern-kit/react를 설치 시 `@types/lodash-es` 를 함께 설치할 수 있도록 `dependencies`로 위치를 변경합니다.
- 관련 PR: https://github.com/modern-agile-team/modern-kit/pull/588
- @types/lodash-es를 제거하고, `throttle/debounce`를 포함한 `lodash.d.ts`을 `@modern-kit/react`에서 직접 제공 할 수 있습니다만... 이 부분은 조금 더 고려가 필요합니다.

<br />

### 추후 계획
- 가능하다면 `lodash-es`를 걷어내고 싶습니다. 예정된 계획은 없지만 추후에 lodash-es를 걷어내는 작업을 할 예정입니다. 🙏