打字稿:创建具有相同键但值不同的对象

时间:2019-05-11 13:11:51

标签: typescript typescript-typings

我有以下初始对象

const initialValues = { name: 'Jon', email: 'jon@me.com' }

除了所有值均为boolean且默认值为false之外,我想创建一个相同的对象。像这样

const expected = { name: false, email: false }

我创建了以下功能来实现我想要的功能

const expected = cloneWithDefaults<typeof initialValues>(initialValues)

function cloneWithDefaults<T>(values: T) {
  type U = { [K in keyof T]: boolean }
  const keys = Object.keys(values) as Array<keyof T>
  const partial: Partial<U> = keys.reduce<Partial<U>>((acc, cur) => {
    acc[cur] = false
    return acc
  }, {})
  const final = partial as U
  return final
}

我还创建了第二个不使用reduce的版本

function createCloneWithDefaultsV2<T extends { [key: string]: unknown }>(values: T) {
  type U = { [K in keyof T]: boolean }
  const keys = Object.keys(values) as Array<keyof U>
  const partial: Partial<U> = {}
  for (let k in keys) {
    partial[k] = false
  }
  const final = partial as U
  return final
}

我想知道是否有更好/更简洁的方法。特别是,如果可能的话,我想摆脱as的两种用法。

在第2版中,我想知道对unknown而不是any的偏好。

2 个答案:

答案 0 :(得分:2)

这是我的写法:

    function cloneWithDefaults<T>(values: T) {
        return <{[key in keyof T]: boolean}> Object.entries(values).reduce((p, [k, v]) => Object.assign(p, { [k]: false }), {});
    }
    const initialValues = { name: 'Jon', email: 'jon@me.com' };
    const expected = cloneWithDefaults(initialValues);

由于reduce()调用,我看不到没有强制转换的选项。 (无论是部分引用还是任意引用。)请注意,Object.entries()要求downlevelIteration ts编译器选项为true(https://www.typescriptlang.org/docs/handbook/compiler-options.html)。

答案 1 :(得分:1)

这里是another alternative,它基于克里斯托夫的答案:

const cloneWithDefaultValues = <T>(input: T) => Object
    .keys(input)
    .reduce(
        (clone, key) => ({ [key]: false, ...clone }),
        {} as Record<keyof T, boolean>
    );