【问题标题】:Object with generic keys in typescript打字稿中具有通用键的对象
【发布时间】:2020-04-20 00:52:44
【问题描述】:

我想创建一个通用函数,它接受一个对象,然后进行一些转换并返回具有相同键和不同值的新对象。我正在尝试使其成为“强类型”,因此使用它的每个人都将受益于 TS,并且不存在的密钥应该引发错误。

我现在拥有的:

const hash = {
  "first": 1,
  "second": 2,
  "third": 3,
}

type Mapper<T> = {
  [key in keyof T]: number
}

type Result<T>= {
  [key in keyof T]: () => number
}

const transform = <T>(mapper: Mapper<T>) => {
  const result = {} as Result<T>

  (Object.keys(mapper) as (keyof T)[]).map(key => {
    result[key] = () => mapper[key]
  })

  return result
}

type Hash = typeof hash

const a = transform<Hash>(hash)

a.first()
// a.fifth() OK error

效果很好,但我正在寻找解决方案:

  1. 移除类型断言const result = {} as Result&lt;T&gt;

  2. 移除类型断言(Object.keys(mapper) as (keyof T)[])(或使用Object.entries,但在这种情况下似乎也需要类型断言)

我可以在 Typescript 中以更“干净”的方式实现相同的功能吗?

【问题讨论】:

    标签: javascript typescript typescript-typings typescript-generics


    【解决方案1】:

    Object.keys 返回 always string[],因此您需要进行强制转换。

    更小更强大的版本将使用reduce。 另一个小的改进是使用原始密钥的类型,T[Key]

    const hash = {
      "first": 'someString',
      "second": 2,
      "third": 3,
    }
    
    type Result<T>= {
      [Key in keyof T]: () => T[Key]
    }
    
    const transform = <T extends object>(obj: T): Result<T> => {
      return (Object.keys(obj) as Array<keyof T>).reduce((result, key) => {
          result[key] = () => obj[key];
          return result;
      }, {} as Result<T>)
    }
    
    const a = transform(hash)
    
    a.first() // returns "string"
    a.second() // return "number"
    

    【讨论】:

    • 我没有看到reduce 增加了任何健壮性(也没有,就此而言,它更小);但它确实比简单地创建一个对象并添加到它增加了复杂性,尤其是引入了忘记return result; 行的枪。由于others have saidreduce 被过度使用。
    • 谁能想到将: 更改为in 会解决这个问题?谢谢!
    猜你喜欢
    • 2019-10-03
    • 1970-01-01
    • 1970-01-01
    • 2020-07-15
    • 2020-01-19
    • 2018-12-29
    • 1970-01-01
    • 1970-01-01
    • 2018-09-23
    相关资源
    最近更新 更多