首页 > 解决方案 > 如何在 TypeScript 的 Input onChange 事件中使用 debounce

问题描述

这是我使用 Debounce 的地方

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

onChange 事件:

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

去抖功能:

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);
  };
}

我在打字稿中遇到参数错误:

TS2554: Expected 0 arguments, but got 1.

我知道这是错误的,但我不知道如何在 Debounce 中传递参数

标签: reactjstypescript

解决方案


首先this是一个特殊的函数参数。this它指定函数中所需的上下文 ( ) 类型。它不能算作一个真正的论点。这意味着这function (this: any) {}是一个接受零参数的函数。


其次,永远不要arguments在打字稿中使用关键字。出于各种原因,它可能很棘手(它不是一个真正的数组,并且无法输入仅举几例)。而是接受映射到变量的一系列参数。

喜欢:

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

第三,Typescript 需要知道从 debounce 中返回的函数类型。Function不够好。它需要知道去抖函数接受的参数。为此,您必须使用泛型类型参数。

这变得有点复杂。

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);
  };
}

这是通用参数:

T extends unknown[]

并在这里使用它作为func参数类型:

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

并且在函数的返回类型中:

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

现在,您传递给的函数debounce的参数将被泛型参数注意到,并且返回的函数将具有完全相同的参数。


最后,您不需要在onChange. React 知道元素的类型,因此 typescript 可以知道参数的类型。

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

TypeScript 操场上的工作示例


推荐阅读