最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Property 'toLowerCase' does not exist on type 'T[keyof T]' - Stack Overflow

programmeradmin7浏览0评论

I am trying to write a function with generic types which takes two args (array of obj and search term) but I am getting an error - Property 'toLowerCase' does not exist on type 'T[keyof T]'

here is the function:

function matchSearchTerm<T>(data: T[], search: string): T[] {
  return data.filter((obj) => {
    const filteredData = (Object.keys(obj) as Array<keyof typeof obj>).some((value) => {
      return (
        typeof obj[value] === "string" && obj[value].toLowerCase().includes(search.toLowerCase())
      );
    });
    return filteredData;
  });
}

What is missing here?

I am trying to write a function with generic types which takes two args (array of obj and search term) but I am getting an error - Property 'toLowerCase' does not exist on type 'T[keyof T]'

here is the function:

function matchSearchTerm<T>(data: T[], search: string): T[] {
  return data.filter((obj) => {
    const filteredData = (Object.keys(obj) as Array<keyof typeof obj>).some((value) => {
      return (
        typeof obj[value] === "string" && obj[value].toLowerCase().includes(search.toLowerCase())
      );
    });
    return filteredData;
  });
}

What is missing here?

Share Improve this question asked Jun 9, 2021 at 9:38 MykytaMykyta 3962 gold badges7 silver badges21 bronze badges 1
  • Your array is of generic type T and the function toLowerCase() is not defined on that type, hence the error message. You need to cast the array item to string. – user1438038 Commented Jun 9, 2021 at 9:52
Add a ment  | 

3 Answers 3

Reset to default 2

Seems related to this issue: https://github./microsoft/TypeScript/issues/10530

You can still pull the obj[value] out into a variable to get the type inference:

function matchSearchTerm<T>(data: T[], search: string): T[] {
  return data.filter((obj) => {
    const filteredData = (Object.keys(obj) as Array<keyof typeof obj>).some((value) => {
      const val = obj[value];
      return (
        typeof val === "string" && val.toLowerCase().includes(search.toLowerCase())
      );
    });
    return filteredData;
  });
}

How about this:

return obj[value]['toLowerCase']?.call(obj[value]).includes(search.toLowerCase())

in my eyes its returning true/false/undefined -> for filters its fine... or we can use some ternary operator, if we want just true/false....

function matchSearchTerm<T extends Record<string, string>>(data: T[], search: string) {
  return data.filter((obj) => {
    const filteredData = (Object.keys(obj) as Array<keyof T>).some((value) => {
      const checkIt = obj[value]
      return (
        typeof obj[value] === "string" && obj[value].toLowerCase().includes(search.toLowerCase())
      );
    });
    return filteredData;
  });
}

Just add extra constraint to your T generic parameter:T extends Record<string, string>

发布评论

评论列表(0)

  1. 暂无评论