【问题标题】:How to type a function for renaming object keys in Typescript如何在 Typescript 中键入用于重命名对象键的函数
【发布时间】:2019-06-13 16:03:26
【问题描述】:

我有一个函数,它接受一个字符串转换函数和一个对象,并将转换应用于所有键,返回结果对象。

特别是我正在使用 Ramda

这是我的函数(为清楚起见,未键入)。

const renameBy = R.curry(
  (fn, obj) => R.pipe(
      R.toPairs,
      R.map([k, v] => [fn(k), v]),
      R.fromPairs
    )(obj)
);

我很清楚 currying 可能导致的问题,所以我真的只是在寻找解决核心函数(以及可选的第二个一元函数 renameBy(fn))并解决比当前更好的返回类型的解决方案R.Dictionary,基本上从不匹配任何东西。

我一直在寻找 here, dealing with renaming specific keys of an object 和 here, dealing with recursive, deep nested-object renaming,但似乎都不是我想要的。

使用示例

const input = {
     foo_bar: "foobar",
     bar: "bar",
     bar_foo: "barfoo"
}

const camelize = (paramName) =>
  paramName.replace(
    /_(.?)/g,
    $1 => $1.substr(1).toUpperCase()
  );

renameBy(camelize, input)

const expectedOutput = {
     fooBar: "foobar",
     bar: "bar",
     barFoo: "barfoo"
}

我可以使用类似的东西

function renameBy<
     F extends (str: string) => string,
     N extends string[],
     M extends Record<string, any>
   >(fn: F, obj: M): { [P in N]: M[keyof M] }
      {...}

但我不能让它工作。

【问题讨论】:

  • 如果您可以静态表示重命名功能,则可以使用something like this 进行打字。但实际上,使用 F,您将能够做的只是像 Record&lt;ReturnType&lt;F&gt;, M[keyof M]&gt; 这样的东西,它相当广泛,可能不值得您花时间
  • 同意@jcalz。简而言之,它不能很好地完成,因为您在运行时使用泛型转换创建了一个新类型。

标签: typescript object key rename


【解决方案1】:

这个问题已经有一段时间没有讨论过了。最近,我面临着类似的任务。无论如何,这是 TS 4.1+ 的可能解决方案

// helper types
type BaseT = Record<string, unknown> // object constraint
type BaseM = Record<string, string> // mapping constraint
type KVs<T extends BaseM> = keyof T | T[keyof T] // keys and values

type Remap<T extends BaseT, M extends BaseM> =
  & {[K in keyof M & keyof T as M[K]]: T[K]} // new keys
  & {[K in keyof T as Exclude<K, KVs<M>>]: T[K]} // unchanged keys

type Result = Remap<{a: 1; b: '2'}, {a: 'c'}>
// type Result = {b: '2'} & {c: 1}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-11-26
    • 2018-05-17
    • 2020-04-01
    • 2021-05-17
    • 1970-01-01
    • 2021-05-20
    • 1970-01-01
    • 2021-02-28
    相关资源
    最近更新 更多