You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何创建类型以断言Test类的所有方法均返回Promise?

实现类方法返回Promise的类型断言

需求

创建一个类型,用于断言Test类中的每个方法都返回Promise。

现有代码

void (async function(){

class Test {
    public a = 1;
    methodA(a: number) {
        return a;
    }
    
    methodB(b: string) {
        return b;
    }
}

type FunctionType<T extends object> = { [k in keyof T]: T[k] extends (...args: any) => any ? k : never }[keyof T];

type TestWithAsyncMethods<T extends object> = {
    [k in FunctionType<T>]: (...args: Parameters<T[k]>) => Promise<ReturnType<T[k]>>;
};

const test = <TestWithAsyncMethods<Test>><unknown>new Test();

const resultA = await test.methodA(1); // methodA: (a: number) => Promise<number>
console.log(resultA);

const resultB = await test.methodB('test'); // methodB: (b: string) => Promise<string>
console.log(resultB);
})();

报错信息

error TS2344: Type 'T[k]' does not satisfy the constraint '(...args: any) => any'.
  Type 'T[FunctionType<T>]' is not assignable to type '(...args: any) => any'.
    Type 'T[T[keyof T] extends (...args: any) => any ? keyof T : never]' is not assignable to type '(...args: any) => any'.
      Type 'T[keyof T]' is not assignable to type '(...args: any) => any'.
        Type 'T[string] | T[number] | T[symbol]' is not assignable to type '(...args: any) => any'.
          Type 'T[string]' is not assignable to type '(...args: any) => any'.

229     [k in FunctionType<T>]: (...args: Parameters<T[k]>) => Promise<ReturnType<T[k]>>;

问题分析

报错根源是TypeScript无法在TestWithAsyncMethods的映射逻辑中,确认T[k]必然是函数类型。虽然FunctionType<T>已经过滤出了类中的函数键,但TS的类型推断机制无法直接关联k对应的T[k]一定满足函数约束,导致Parameters和ReturnType工具类无法正常工作。

修正方案

直接通过条件类型+映射的方式遍历类的所有属性:对函数类型的属性,自动将其返回值包装为Promise;非函数类型的属性保留原类型(也可根据需求直接排除)。

修正后的代码:

void (async function(){

class Test {
    public a = 1;
    methodA(a: number) {
        return a;
    }
    
    methodB(b: string) {
        return b;
    }
}

// 遍历所有属性:函数则包装返回值为Promise,非函数保留原类型
type TestWithAsyncMethods<T extends object> = {
    [K in keyof T]: T[K] extends (...args: infer Args) => infer Ret
        ? (...args: Args) => Promise<Ret>
        : T[K];
};

// 类型断言转换实例类型
const test = new Test() as TestWithAsyncMethods<Test>;

const resultA = await test.methodA(1); // 类型自动推断为Promise<number>
console.log(resultA);

const resultB = await test.methodB('test'); // 类型自动推断为Promise<string>
console.log(resultB);
})();

效果说明

  • TestWithAsyncMethods类型会自动识别类中的函数属性,保留原参数类型的同时,将返回值强制包装为Promise;
  • 非函数属性(如Test类中的a)保持原类型不变;
  • 简化了原代码中的双重断言写法,类型推断更清晰准确。

内容的提问来源于stack exchange,提问作者stackhatter

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 14:13:11