Búsqueda de sitios web

reactjs - ¿Cómo utilizo debounce en los eventos onChange de Input en TypeScript?


Aquí es donde uso Debounce

const handleSearch = debounce((value: string) => {
    const filter = tableDataCopy.filter(
      (item) => item[condition].toLowerCase().indexOf(value) !== -1,
    );
    setTableData(filter);
  }, 500);

Evento onChange:

onChange={(e: ChangeEvent<HTMLInputElement>) => handleSearch(e.target.value)}

función de rebote:

export function debounce(func: Function, delay: number) {
  let timer: NodeJS.Timeout | null = null;
  return function (this: any) {
    if (timer) clearTimeout(timer);
    timer = setTimeout(() => {
      func.call(this, ...arguments);
    }, delay);
  };
}

Obtuve un error de parámetro en TypeScript :

TS2554: Expected 0 arguments, but got 1.

Sé que esto está mal, pero no sé cómo pasar el argumento en Debounce

Respuesta #1

Primero que nada, this es un argumento especial de función. Especifica el tipo requerido del contexto (this) en una función. No cuenta como un argumento real. Esto significa que function (this: any) {} es una función que no toma ningún argumento.


En segundo lugar, nunca uses la palabra clave arguments en TypeScript. Puede ser complicado, por una variedad de razones (no es un array real, y no se le puede asignar un tipo, por nombrar algunas). En su lugar, acepta un conjunto de argumentos que se asignen a una variable.

Me gusta :

function (...args: string[]) {}

Tercero, TypeScript necesita conocer el tipo de función que se devuelve de tu debounce. Function no es suficientemente bueno. Necesita saber los argumentos que acepta tu función con debounce. Para esto, tienes que usar un parámetro de tipo genérico.

Esto se complica un poco más.

function debounce<
  T extends unknown[]
>(
  func: (...args: T) => void,
  delay: number,
):
  (...args: T) => void
{
  let timer: number | null = null;
  return (...args: T) => {
    if (timer) clearTimeout(timer);
    timer = setTimeout(() => {
      func.call(null, ...args);
    }, delay);
  };
}

Este es el parámetro genérico:

T extends unknown[]

Y úsalo aquí como el tipo de argumento func:

func: (...args: T) => void

Y en el tipo de retorno de la función:

: (...args: T) => void

Ahora la función que pases a debounce tendrá sus argumentos reconocidos por el parámetro genérico, y la función devuelta tendrá exactamente los mismos argumentos.


Por último, no necesitas especificar el tipo de evento en onChange. React conoce el tipo del elemento, por lo que TypeScript puede conocer el tipo de los argumentos.

<input type="text" onChange={e => handleSearch(e.target.value)} />

Ejemplo funcional en un entorno de prueba de TypeScript

Artículos relacionados