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

如何在TypeScript中根据标志返回Promise或值并实现正确类型推断?

如何让TypeScript根据驱动类型自动区分同步/异步方法的返回值?

要实现让TypeScript根据驱动类型强制区分set方法的返回值(同步驱动返回boolean,异步驱动返回Promise<boolean>),核心是利用泛型+条件类型,让类的方法返回值与驱动类型绑定,从而让TS在实例化时自动推断正确的类型。

解决方案步骤

  1. 明确驱动的类型区分
    基于你现有的checkDriverIsAsync函数,构建类型层面的同步/异步判断逻辑,让TS能识别驱动的特性。

  2. 用泛型绑定驱动类型
    将GoodDB改为泛型类,泛型参数绑定具体驱动类型,使类的方法和属性类型能动态依赖这个参数。

  3. 用条件类型定义返回值
    通过条件类型判断泛型参数对应的驱动是同步还是异步,以此指定set方法的返回值类型。

完整代码示例

1. 基础类型定义(复用你现有逻辑)

// 同步驱动与异步驱动的基础类型
type SyncDriver = {
  // 同步驱动的核心方法
  setSync(key: string, value: any): boolean;
};
type AsyncDriver = {
  // 异步驱动的核心方法
  setAsync(key: string, value: any): Promise<boolean>;
};
type Drivers = SyncDriver | AsyncDriver;

// 你原有的驱动异步判断函数
function checkDriverIsAsync(driver: Drivers): boolean {
  return 'setAsync' in driver;
}

// 基于函数返回值构建类型层面的异步判断
type IsAsync<D extends Drivers> = ReturnType<typeof checkDriverIsAsync> extends true ? true : false;

2. 改造后的GoodDB类

class GoodDB<D extends Drivers> {
  private driver: D;
  public readonly isAsync: IsAsync<D>;

  constructor(
    driver: D,
    private options?: any
  ) {
    this.driver = driver;
    this.isAsync = checkDriverIsAsync(driver) as IsAsync<D>;
  }

  set(key: string, value: any, options?: any): IsAsync<D> extends true ? Promise<boolean> : boolean {
    if (this.isAsync) {
      // 异步逻辑执行
      return (async () => {
        // 这里替换为你的异步驱动处理逻辑
        return await this.driver.setAsync(key, value);
      })() as IsAsync<D> extends true ? Promise<boolean> : boolean;
    } else {
      // 同步逻辑执行
      return this.driver.setSync(key, value) as IsAsync<D> extends true ? Promise<boolean> : boolean;
    }
  }
}

3. 实例化验证

// 同步驱动实例
const syncDriver: SyncDriver = {
  setSync(key: string, value: any): boolean {
    // 同步存储逻辑
    return true;
  }
};
const syncDb = new GoodDB(syncDriver);
const syncResult = syncDb.set('key', 'value'); 
// TS自动推断为boolean,无await提示

// 异步驱动实例
const asyncDriver: AsyncDriver = {
  async setAsync(key: string, value: any): Promise<boolean> {
    // 异步存储逻辑
    return true;
  }
};
const asyncDb = new GoodDB(asyncDriver);
const asyncResult = await asyncDb.set('key', 'value'); 
// TS自动推断为Promise<boolean>,必须使用await,否则会报错

为什么之前的方法无效?

你之前使用的方法重载是静态的,TypeScript无法根据实例的isAsync属性动态调整返回值类型——重载是针对整个类的所有实例,而泛型是在实例化时确定具体类型,因此能让TS精准推断每个实例的方法返回值。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 18:51:16