【问题标题】:Typesafe convertion of one object to another (aka pick)一个对象到另一个对象的类型安全转换(akka pick)
【发布时间】:2020-08-27 07:45:56
【问题描述】:

我有很多具有已知类型的对象,我需要将这些对象转换为具有已知类型的其他对象,如下所示:

interface FruitesWithNoCase = {
  brokenbanana: string;
  brokenorange: string;
  apple: number;
}

interface FruitesWithCorrectCase = {
  brokenBanana: string;
  brokenOrange: string;
}

const inputObject: FruitesWithNoCase = { // My input data
  brokenbanana: 'foo',
  brokenorange: 'bar',
  apple: 123
}

const outputObject: FruitesWithCorrectCase = { // Desired result
  brokenBanana: 'foo',
  brokenOrange: 'bar'
}

我不想手动映射每个对象,如果有一些函数可以接受 X 类型的输入对象和属性数组并返回和输出 Y 类型的对象,那就太好了,例如:

const outputObject = getAttributes<FruitesWithNoCase, FruitesWithCorrectCase, (keyof FruitesWithCorrectCase)[]>(inputObject, ['brokenBanana', 'brokenOrange']);
  1. 总是有输入和输出类型
  2. 总是有我需要在 camelCase 中选择的属性列表
  3. 总是确定output[prop.toLowerCase()] 存在于input

没有类型的工作代码如下所示:

const inputObject = {
  "brokenbanana": 'foo',
  "brokenorange": 'bar',
  "apple": 123
}

const anotherInputObject = {
  "randomcar": "Fiat",
  "randomtruck": "Ford"
}

function getAttributes(obj, keys) {
  return keys.reduce((acc, key) => {
    acc[key] = obj[key.toLowerCase()]
    return acc;
  }, {});  
}

const outputObject = getAttributes(inputObject, ['brokenBanana', 'brokenOrange']);
const anotherOutputObject = getAttributes(anotherInputObject, ['randomCar'])

console.log(outputObject); // { brokenBanana: 'foo', brokenOrange: 'bar' }
console.log(anotherOutputObject); // { randomCar: 'Fiat' }

请帮助使这个函数类型安全。谢谢。

【问题讨论】:

    标签: typescript typescript-generics


    【解决方案1】:

    这样的东西有用吗?

    function getAttributes<T extends string>(obj: Record<string, string> , keys: T[]): Record<T, string> {
      return keys.reduce((acc, key) => {
        acc[key] = obj[key.toLowerCase()]
        return acc;
      }, {} as Record<T, string>);  
    
    }
    

    【讨论】:

      【解决方案2】:

      您不能真正为对象的“toLowerCase”键并期望它是类型安全的。如果你想要完美的类型安全,下面可能是你能得到的最好的。

      const inputObject = { // My input data
          brokenbanana: 'foo',
          brokenorange: 'bar',
          apple: 123
      }
      
      const outputObject = move(inputObject, ["brokenbanana", "brokenBanana"], ["brokenorange", "brokenOrange"])
      
      function move<T, Old extends keyof T, New extends keyof any>(obj: T, ...map: Array<[Old, New]>): Record<New, T[Old]> {
          const copy = {} as Record<New, T[Old]>;
          map.forEach(([o, n]) => copy[n] = obj[o])
          return copy
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2013-09-18
        • 2021-10-30
        • 2021-08-14
        • 1970-01-01
        • 2015-11-19
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多