You need to tell the type of object that reduce
uses for accumulator.
const originObj = {
a: 1,
b: 'string',
c: () => {}
};
function getObjKeyMap<T>(obj: T) {
return Object.keys(obj).reduce((acc, k) => {
acc[k] = k;
return acc;
}, {} as Record<string, string>);
}
// or
function getObjKeyMap1<T>(obj: T) {
return Object.keys(obj).reduce((acc: Record<string, string>, k: string) => {
acc[k] = k;
return acc;
}, {});
}
const keyMap = getObjKeyMap(originObj);
TS Playground
However, I bet this is not the best solution. I bet there is a way to write a function declaration like this:
function getObjKeyMap<T, K extends keyof T>(obj: T): Record<K, K>
Where Typescript automatically tells you that getObjectMap({a: 1, b: 'string', c: () => {}}
returns {a: "a", b: "b", c: "c"}
.
I think this is much better:
const originObj = {
a: 1,
b: 'string',
c: () => {}
};
type KeyMap<T> = {
[key in keyof T]: key
};
function getObjKeyMap<T>(obj: T): KeyMap<T> {
return Object.keys(obj).reduce((acc, k) => ({...acc, k: k}), {} as KeyMap<T>);
}
const keyMap = getObjKeyMap<typeof originObj>(originObj);
TS Playground
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…