
Nextjs + Typescript 기반의 프로젝트에서 debounce가 필요했다.
내가 만들고자 했던 것은
모든 타입의 인자를 허용하며 void 타입을 반환하는 함수와,
debounce 의 delay time(기본 값: 200)을 인자로 받아,debounce가 적용된 함수를 반환하는 훅이었다.
그래서 다음과 같이 코드를 작성했다.
// useDebounceCallback.ts - 수정 전
// ...args: any[]
import { useRef } from "react";
function useDebounceCallback<T extends (...args: any[]) => void>(callback: T, delay: number = 200) {
const timeoutRef = useRef<number | null>(null);
return (...args: Parameters<T>) => {
if (timeoutRef.current) {
clearTimeout(timeoutRef.current);
}
timeoutRef.current = window.setTimeout(() => {
callback(...args);
}, delay);
};
}
// 사용 예제
const debouncedFunction = useDebounceCallback((e: UIEvent) => {
console.log(e.target);
}, 200);
빌드 후 실행이 되지만
...args: any[]구문에서? eslint 경고가 발생했다.
Unexpected any. Specify a different type. eslint@typescript-eslint/no-explicit-any
TypeScript에서 any 타입 사용을 제한하는 ESLint 규칙이라고 한다.
대부분의 TypeScript 프로젝트에서는 경고 또는 오류로 설정되어 있다.
가능한 구체적인 타입을 명시 (예: string, number, CustomType 등)
function log(data: string | number | boolean) {
console.log(data);
}
unknown 사용 후 타입 가드로 처리
function process(input: unknown) {
// input.toUpperCase(); ❌ 오류!
if (typeof input === 'string') { // ✅ 타입 좁히기 후 사용 가능
input.toUpperCase();
}
}
규칙 비활성화 (비추천)
// eslint-disable-next-line @typescript-eslint/no-explicit-any
function handle(data: any) {
// 예외적으로 any 허용
}
나의 경우, callback 함수의 인자는 모든 타입을 허용해야한다.
그러나 위에서 설명한 것과 같이
비추천이다.말 그대로
타입스크립트이기 때문에
any타입을 무자비하게 허용하게 된다면
타입을 강제함으로써 코드의 안정성을 높이자는 타입스크립트의 목적을 상실하기 때문이다.
import { useRef } from "react";
function useDebounceCallback<Args extends unknown[]>(callback: (...args: Args) => void, delay: number = 200) {
const timeoutRef = useRef<number | null>(null);
return (...args: Args) => {
if (timeoutRef.current) {
clearTimeout(timeoutRef.current);
}
timeoutRef.current = window.setTimeout(() => {
callback(...args);
}, delay);
};
}
export default useDebounceCallback;