type HasFunc = T extends (...args: unknown[]) => unknown ? true : T extends unknown[] ? { [K in keyof T]: HasFunc; }[number] extends false ? false : true : T extends object ? { [K in keyof T]: HasFunc; }[keyof T] extends false ? false : true : false; type ToFunc = { [K in keyof T]: T[K] extends (...args: infer Args) => infer Ret ? (...args: Args) => Promise> : HasFunc extends false ? () => Promise : T[K] extends object ? ToFunc : never; }; interface RemoteCallData { paths: string[]; args: unknown[]; } type Assert = T; interface TestObj { a1: number; a2: number[]; a3: [number, string]; a4: { b: number; c: [string]; }; a5: () => Promise; a6: () => Promise; a7: () => Promise<[number, string]>; b: { b1: number; b2: number[]; b3: [number, string]; b4: () => { b: number; c: [string]; }; b5: () => Promise; b6: () => Promise; b7: () => Promise<[number, string]>; }; f: { b: number; c: { d: () => number; }; }; } type TestA1 = Assert['a1'] extends () => Promise ? true : false>; type TestA2 = Assert['a2'] extends () => Promise ? true : false>; type TestA3 = Assert['a3'] extends () => Promise<[number, string]> ? true : false>; type TestA4 = Assert['a4'] extends () => Promise<{ b: number; c: [string]; }> ? true : false>; type TestA5 = Assert['a5'] extends () => Promise ? true : false>; type TestA6 = Assert['a6'] extends () => Promise ? true : false>; type TestA7 = Assert['a7'] extends () => Promise<[number, string]> ? true : false>; type TestB1 = Assert['b']['b1'] extends () => Promise ? true : false>; type TestB2 = Assert['b']['b2'] extends () => Promise ? true : false>; type TestB3 = Assert['b']['b3'] extends () => Promise<[number, string]> ? true : false>; type TestB4 = Assert['b']['b4'] extends () => Promise<{ b: number; c: [string]; }> ? true : false>; type TestB5 = Assert['b']['b5'] extends () => Promise ? true : false>; type TestB6 = Assert['b']['b6'] extends () => Promise ? true : false>; type TestB7 = Assert['b']['b7'] extends () => Promise<[number, string]> ? true : false>; type TestF = Assert['f']['b'] extends () => Promise ? true : false>; type TestF2 = Assert['f']['c']['d'] extends () => Promise ? true : false>; export type { RemoteCallData, TestA1, TestA2, TestA3, TestA4, TestA5, TestA6, TestA7, TestB1, TestB2, TestB3, TestB4, TestB5, TestB6, TestB7, TestF, TestF2, ToFunc };