我有两个对象,我的自定义映射函数将一个对象的道具映射到另一个对象的值,例如:
const obj1 = {
host: 'clientNameHost',
pass: 'clientNamePass',
};
const obj2 = {
clientNamePass: '12345',
clientNameHost: 'http://localhost:3000',
};
const mapParams = <T, K>(source: T, params: K) => Object.entries(params)
.reduce((acc, [param, sourceProp]) => ({ ...acc, [param]: source[sourceProp] }), {});
mapParams(obj2, obj1) //{host: "http://localhost:3000", pass: "12345"}
我很难过,试图键入此函数。有什么方法可以正确键入mapParams函数吗?
解决方案是缩小泛型类型,以显示两个参数中的键和值之间的关系:
const obj1 = {
host: 'clientNameHost',
pass: 'clientNamePass',
} as const;
const obj2 = {
clientNamePass: '12345',
clientNameHost: 'http://localhost:3000',
} as const;
const mapParams = <T extends Record<string, any>, K extends keyof T, P extends Record<T[K], any>>(source: T, params: P) => Object.entries(params)
.reduce((acc, [param, value]) => ({ ...acc, [param]: source[value as T[K]] }), {});
console.log(mapParams(obj1, obj2)) //{host: "http://localhost:3000", pass: "12345"}
关键部位:
T extends Record<string, any>
第一种类型是带有字符串键的记录K extends keyof T
代表T
的键P extends Record<T[K], any>
关键部分-我们想要在T
]中具有相等键值的对象>as const
是为了正确推断缩小的类型以上类型在第一个参数值和第二个参数键之间创建一个边界。