首页 > 解决方案 > 如何在 TypeScript 中将对象属性作为参数传递

问题描述

我正在尝试使用 TypeScript 编写自定义反应钩子。我编写了简单的辅助函数,它可以帮助我检查目标对象中是否存在这样的属性:

export function hasOwnProperty<X extends {}, Y extends PropertyKey>(
  obj: X,
  prop: Y,
): obj is X & Record<Y, unknown> {
  return obj.hasOwnProperty(prop);
}

我正在尝试在我的钩子中使用它:

export const useAutocomplete = <T, Y extends PropertyKey>(data: Array<T>, property?: Y) => {
  const [query, setQuery] = useState('');
  const [results, setResults] = useState<T[]>([]);

  const findResults = (element: T) => {
    if (property && hasOwnProperty(element, property)) {
      return String(element[property])
        .toLowerCase()
        .includes(query.toLowerCase());
    }
    return String(element).toLowerCase().includes(query.toLowerCase());
  };

  // ...other code

};

toLowerCase()问题是即使我检查if (typeof obj[property] === 'string')它不起作用,我也不能使用像和其他方法。这就是为什么我决定将我的对象包装在 String 中,然后我可以访问我需要的方法。但我认为这不是一个好的解决方案,我想问什么是更好的解决方法?

标签: typescriptreact-typescript

解决方案


打字稿不知道什么是T

明确告诉打字稿你T是一个带有字符串值的对象

T extends { [key: string]: string}

完整代码

export const useAutocomplete = <T extends { [key: string]: string }, Y extends PropertyKey>(data: Array<T>, property?: Y) => {
  const [query, setQuery] = useState('');
  const [results, setResults] = useState<T[]>([]);

  const findResults = (element: T) => {
    if (property && hasOwnProperty(element, property)) {
      return element[property]
        .toLowerCase()
        .includes(query.toLowerCase());
    }
    return String(element).toLowerCase().includes(query.toLowerCase());
  };

  // ...other code

};

推荐阅读