如何正确键入将多个对象合并在一起的动态递归函数?
我正在尝试键入以下函数,该函数按预期工作,但未正确键入。我希望它在我键入时为我自动建议可用值。
我对打字稿比较陌生,但我一直无法弄清楚。这是我所拥有的:
const endpointsA = (base: string) => ({
GET: {
FEATURE_A: {
SOME_PATH: `${base}/featureA`,
},
},
});
const endpointsB = (base: string) => ({
GET: {
FEATURE_B: {
SOME_PATH: `${base}/featureB`,
},
},
POST: {
FEATURE_B: {
SOME_PATH: `${base}/featureB`,
},
},
});
type TMergeEndpoints = {
[key: string]: Record<string, unknown>;
}[];
type TRecursiveMerge = {
obj: {
[key: string]: Record<string, unknown>;
};
entries: Array<[string, Record<string, unknown>]>;
};
const mergeEndpoints = (endpoints: TMergeEndpoints) => {
const result = {};
const recursiveMerge = ({ obj, entries }: TRecursiveMerge) => {
for (const [key, value] of entries) {
if (typeof value === 'object') {
obj[key] = obj[key] ? { ...obj[key] } : {};
recursiveMerge({
obj: obj[key] as TRecursiveMerge['obj'],
entries: Object.entries(value) as TRecursiveMerge['entries'],
});
} else {
obj[key] = value;
}
}
return obj;
};
endpoints.forEach((endpoint) => {
recursiveMerge({ obj: result, entries: Object.entries(endpoint) });
});
return result;
};
const base = '/api';
const endpoints = mergeEndpoints([
endpointsA(base),
endpointsB(base),
]);
console.log('endpoints', endpoints);
这正确合并了我的对象,但是我没有收到任何类型建议。我试过玩弄<T>,把它放在这里和那里,但效果不太好。我能在这里做什么?
打字稿游乐场
编辑
最终使用了迈克尔的建议并得到了这样的结果:
/**
Each type has a definition for each entry that it has.
For example,
const a = (base: string): A => ({
GET: {
FEATURE_A: {
SOME_PATH: `${base}/some-path`
}
}
});
type A = {
GET: {
FEATURE_A: {
SOME_PATH: string
}
}
}
*/
type TEndpoints = A & B & C;
const endpoints = mergeEndpoints<TEndpoints>([a(base), b(base), c(base)]);
/**
`mergeEndpoints` stayed the same with one exception (I pass T into it during runtime)
*/
type TMergeEndpoints = {
[key: string]: Record<string, unknown>;
}[];
type TRecursiveMerge = {
obj: {
[key: string]: Record<string, unknown>;
};
entries: Array<[string, Record<string, unknown>]>;
};
export const mergeEndpoints = <T>(endpoints: TMergeEndpoints): T => {
const result = {};
const recursiveMerge = ({ obj, entries }: TRecursiveMerge) => {
for (const [key, value] of entries) {
if (typeof value === 'object') {
obj[key] = obj[key] ? { ...obj[key] } : {};
recursiveMerge({
obj: obj[key] as TRecursiveMerge['obj'],
entries: Object.entries(value) as TRecursiveMerge['entries'],
});
} else {
obj[key] = value;
}
}
return obj;
};
endpoints.forEach((endpoint) => {
recursiveMerge({ obj: result, entries: Object.entries(endpoint) });
});
return result as T;
};
游乐场链接