我有一个函数,它带有一个字符串转换函数和一个对象,并将转换应用于所有键,并返回结果对象。
特别是我在使用Ramda
这是我的功能(为清晰起见,未键入)。
const renameBy = R.curry(
(fn, obj) => R.pipe(
R.toPairs,
R.map([k, v] => [fn(k), v]),
R.fromPairs
)(obj)
);
我很清楚currying可能引起的问题,所以我真的只在寻找解决核心函数(以及可选的第二个一元函数namedBy(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] }
{...}
但是我不能完全正常工作。
答案 0 :(得分:0)
距离讨论这个问题已经有一段时间了。最近,我面临着类似的任务。无论如何,这是 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}