泛型第一次赋值就确定了,第二次就有类型限制了

来源:1-1 课程导学

小鹏友的小弟

2021-11-01

图片描述
图片描述
这里他说 string[] | number[]类型的参数不能赋值给string[]类型的参数。我看不懂他的这个错误是啥意思诶,我好像并没有给她string[] | number[] 类型啊,是因为它第一次获取到string[]的时候,T就具象化为string[]了嘛,这种情况应该怎么解决啊,我把arry类型变成any的话,返回值的类型就是两个unkonw了。不知道咋办比较好

写回答

3回答

keviny79

2021-11-03

这是目前 工作中 TS 对象备份最好的方法了! 我提供的这种方案即避免了错误,而且具有通用性!把这段代码封装起来就可以变成一种通用写法,这才是关键!你可以自己试试其他方法,对比下,不是有错误,就是提出来不方便!

1
3
小鹏友的小弟
非常感谢!
2021-11-04
共3条回复

keviny79

2021-11-02

//   我提供解决方案如下:我提供完整通用性的实现的方案,你可以先对老师的答案思考下,留一个思考的空间给你!

const hasOwnProperty = Object.prototype.hasOwnProperty

export const hasOwn = (

  val: object,

  key: string | symbol

): key is keyof typeof val => hasOwnProperty.call(val, key)



const GetSlaParams = <T extends object>(data_: T) => {


  let copyData = {}

  for (let key in data_) {

    if (hasOwn(data_, key)) {

      console.log(key)

      copyData[key] = data_[key]

    }

  }

  return Object.keys(copyData).map((key) => {

    if (hasOwn(copyData, key)) {

      return formatSlectObjList(copyData[key])

    }

    return {}

  })

}

const formatSlectObjList = <T>(arr: T[]): { label: T, value: T }[] => {

  const value = arr.map((item: T) => {

    return { label: item, value: item }

  })

  return value

}


let result = GetSlaParams(data)

console.log("result:", result)



0
3
keviny79
回复
小鹏友的小弟
这是目前 工作中 TS 对象备份最好的方法了! 我提供的这种方案即避免了错误,而且具有通用性!把这段代码封装起来就可以变成一种通用写法,这才是关键!你可以自己试试其他方法,对比下,不是有错误,就是提出来不方便!
2021-11-03
共3条回复

keviny79

2021-11-02

// 错误原因,这个解决方案解决不了你的问题,我发一个解决方案,我提供完整实现的方案,你可以先对老师的答案思考下,留一个思考的空间给你!

const GetSlaParams = async () => {

  const copyData = data

  type keyType = keyof typeof copyData

  let arr = (Object.keys(data) as keyType[])

  formatSlectObjList(data["date"])   // 单独string[]没问题

  formatSlectObjList(data["sre_uid"])//  单独number[]没问题

  return arr.map(key => {

    //1 错误原因: 这是 TS 处理 map 泛型机制引起的,记住规律即可

    // 1.1 对于实参这样来处理:

    // 编译期间 在 map 内部会这样来处理实参 data[key]

    //    把 所有的 data[key] 中的类型全部联合起来

    //  合成联合类型-> (string |number) []

    //

    //  1.2 但对于形参接受并不能一下全部接受,只能一个一个的接受

    //  这样先传入进去的为string[], 这就导致形参和实参类型不一致

    formatSlectObjList(data[key])

  })

}


0
0

晋级TypeScript高手,成为抢手的前端开发人才

轻松驾驭 TypeScript 高级用法, 突破前端成长瓶颈

871 学习 · 425 问题

查看课程