diff --git a/packages/backend/src/services/chart/core.ts b/packages/backend/src/services/chart/core.ts index ddcedba94be4a850a6a8978878fc25871f7fa47c..cc10900e9f76de9842e6c3a4b82cd5ddb2bee23b 100644 --- a/packages/backend/src/services/chart/core.ts +++ b/packages/backend/src/services/chart/core.ts @@ -70,6 +70,18 @@ type ChartResult<T extends Schema> = { [P in keyof T]: number[]; }; +type UnionToIntersection<T> = (T extends any ? (x: T) => any : never) extends (x: infer R) => any ? R : never; + +type UnflattenSingleton<K extends string, V> = K extends `${infer A}.${infer B}` + ? { [_ in A]: UnflattenSingleton<B, V>; } + : { [_ in K]: V; }; + +type Unflatten<T extends Record<string, any>> = UnionToIntersection< + { + [K in Extract<keyof T, string>]: UnflattenSingleton<K, T[K]>; + }[Extract<keyof T, string>] +>; + /** * 様々ãªãƒãƒ£ãƒ¼ãƒˆã®ç®¡ç†ã‚’å¸ã‚‹ã‚¯ãƒ©ã‚¹ */ @@ -642,12 +654,12 @@ export default abstract class Chart<T extends Schema> { } @autobind - public async getChart(span: 'hour' | 'day', amount: number, cursor: Date | null, group: string | null = null): Promise<Record<string, unknown>> { + public async getChart(span: 'hour' | 'day', amount: number, cursor: Date | null, group: string | null = null): Promise<Unflatten<ChartResult<T>>> { const result = await this.getChartRaw(span, amount, cursor, group); const object = {}; for (const [k, v] of Object.entries(result)) { nestedProperty.set(object, k, v); } - return object; + return object as Unflatten<ChartResult<T>>; } }