首页 > 解决方案 > 用 key 中的泛型类型来实现这一点的优雅方式

问题描述

我编写了一个代码来过滤我的对象的任何字段,无论通过创建泛型类型接收到的类型如何,但是我没有在打字稿中找到一种优雅的方法,还有其他方法吗?

type Test = {
  id: number;
  name: string;
  actived: boolean;
}

const dd: Array<Test> = [
  {id: 2, name: "sss", actived: true},
  {id: 3, name: "tt", actived: false},
  {id: 4, name: "mmmmm", actived: true},
  {id: 5, name: "tttt", actived: true}
]
const run = <T, K extends keyof T>(datas: Array<T>, key: K) => {
  return datas.filter(data => castTForFilter(data[key]))
}

const castTForFilter = <K,v = null>(key: K): boolean => {
  switch(typeof key) {
    case "string":
      return key.includes("tt")
    case "number":
      return key == 2
    case "boolean":
      return key == true
    default:
      return false
  }
}

console.log(run(dd, "name"))
console.log(run(dd, "id"))
console.log(run(dd, "actived"))

标签: typescriptobjecttypes

解决方案


@captain-yossarian 你的代码或多或少比我的优雅,但我希望用类型解决这个问题,而不是 typecript 提供的,但没关系。

你的代码:

type Test = {
    id: number;
    name: string;
    actived: boolean;
}
const customData: Test[] = [
    { id: 2, name: "sss", actived: true },
    { id: 3, name: "tt", actived: false },
    { id: 4, name: "mmmmm", actived: true },
    { id: 5, name: "tttt", actived: true }
]

const run = <
    Elem extends Test,
    Data extends Elem[],
    >(data: [...Data], cb: (elem: Elem) => boolean) => data.filter(cb)



const castTForFilter = <Key extends keyof Test>(key: Key) =>
    <Elem extends Test>(elem: Elem) => {
        const value = elem[key]
        switch (typeof value) {
            case "string":
                return value.includes("tt")
            case "number":
                return value == 2
            case "boolean":
                return value == true
            default:
                return false
        }
    }


const result = run(customData, castTForFilter('id'))
console.log(result)

推荐阅读