简体   繁体   English

打字稿中具有通用键的对象

[英]Object with generic keys in typescript

I'd like to create a common function which will take an object, then do some transformations and return new object with same keys and different values.我想创建一个通用函数,它将接受一个对象,然后进行一些转换并返回具有相同键和不同值的新对象。 I'm trying to make it "strongly-typed", so everyone who uses it will have benefits of TS and non-existing keys should throw an error.我试图使它成为“强类型”,因此使用它的每个人都将受益于 TS 并且不存在的键应该抛出错误。

What I have for now:我现在所拥有的:

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

It works well, but I'm looking for solutions to solve this:它运作良好,但我正在寻找解决方案来解决这个问题:

  1. Remove type assertion const result = {} as Result<T>删除类型断言const result = {} as Result<T>

  2. Remove type assertion (Object.keys(mapper) as (keyof T)[]) (or use Object.entries , but seems it also requires type assertion in this case)删除类型断言(Object.keys(mapper) as (keyof T)[]) (或使用Object.entries ,但在这种情况下似乎也需要类型断言)

Could I implement the same, but in more "clean" way in Typescript?我可以在 Typescript 中以更“干净”的方式实现相同的功能吗?

Object.keys returns always string[] therefore you will need the casting. Object.keys始终返回string[]因此您需要进行转换。

A smaller & more robust version would use reduce .更小、更健壮的版本将使用reduce Another small improvement would be to use the type of the original key, with T[Key] .另一个小的改进是使用原始密钥的类型,以及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"

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM