ts报错, 该怎么解决呢 ?

不能将类型“string[]”分配给类型“K”。 "string[]" 可赋给 "K" 类型的约束,但可以使用约束 "readonly string[]" 的其他子类型实例化 "K"
image.png

function getMapObj2<T extends Record<string, any>, K extends readonly string[]>(originObj: T, keyArr2: K): {
  [Key in typeof keyArr2[number]]: T[Key]
} {
  // let originObj = JSON.parse(JSON.stringify(originObj))
  let obj3 = {}
  keyArr2 = keyArr2.filter(Boolean)
  Object.keys(originObj).filter(v => keyArr2.includes(v)).forEach(v => {
    obj3[v] = originObj[v]
  })
  return obj3 as { [Key in K[number]]: T[Key]; }
}
let obj4 = {
  a: [1, 2, 3],
  b: 'xx',
  c: 3,
  d: false
}
let arr2 = ['a', 'b', 'd'] as const


let obj2 = getMapObj2(obj4, arr2)
console.log('obj2', obj2);
阅读 3.1k
1 个回答

错误提示看到脑壳痛 …… 反正分析一下就是

  • keyArr2K 类型的
  • K 类型是一个 readonly 类型
  • readonly 类型不能赋值

所以不要用 keyArr2 = ...,定义一个新的变量来赋值就好了。虽然也可以把类型参数中的 readonly 约束去掉,但是不建议这么干。

另外 filter(Boolean) 似乎只把 "" 的情况过滤掉了,这个逻辑是可以合并到 Object.keys(originObj).filter 中的,这样不需要先处理 keyArr2

Object.keys(originObj).filter(v => v && keyArr2.includes(v))
//                                 ^^^^^

整个函数体似乎可以用 Object.entries()Object.fromEntires() 加一个过滤来完成,不用先取 Key 再拼对象这么绕(虽然逻辑是一样的)。

    return Object.fromEntries(
        Object.entries(originObj).filter(([key]) => key && keyArr2.includes(key))
    ) as { [Key in K[number]]: T[Key]; }
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题