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

TypeScript中如何利用泛型void类型实现参数可选

问题描述

我想创建一个能返回接收泛型类型参数的类实例的类,有时这个泛型参数可能不存在。我不想让参数处于可能为undefined的状态,因此考虑使用void类型,但遇到了问题:当泛型类型为void时,必须传入undefined值。我想知道能不能直接调用Result.ok()而不传入任何参数?

class Result<A>{

  private constructor(private readonly data: A){}

  static ok<A>(data: A): Result<A> {
    return new Result<A>(data);
  }

  print(): void {
    console.log(this.data ?? 'void');
  }
}

interface IUseCase<A> {
  execute(): Result<A>;
}

class UseCaseVoid implements IUseCase<void> {

  execute(): Result<void> {
    
    // 这里是问题所在:必须传入undefined值
    const result = Result.ok(undefined);

    result.print();

    return result;
  }
}

class UseCaseString implements IUseCase<string> {

  execute(): Result<string> {

    const result = Result.ok('string');
    result.print();
    return result;

  }
}


const useCaseVoid = new UseCaseVoid();

useCaseVoid.execute(); // 输出 void

const useCaseStr = new UseCaseString();

useCaseStr.execute(); // 输出 string
解决方案

可以通过给Result.ok添加重载签名,实现泛型为void时无需传参的需求,同时保证其他类型的类型安全:

class Result<A>{

  private constructor(private readonly data: A){}

  // 重载:泛型为void时无需传参
  static ok(): Result<void>;
  // 重载:泛型为其他类型时必须传入对应参数
  static ok<A>(data: A): Result<A>;
  // 方法实现
  static ok<A>(data?: A): Result<A | void> {
    return new Result(data as A);
  }

  print(): void {
    console.log(this.data ?? 'void');
  }
}

interface IUseCase<A> {
  execute(): Result<A>;
}

class UseCaseVoid implements IUseCase<void> {
  execute(): Result<void> {
    // 现在可以直接调用Result.ok(),无需传参
    const result = Result.ok();
    result.print();
    return result;
  }
}

class UseCaseString implements IUseCase<string> {
  execute(): Result<string> {
    const result = Result.ok('string');
    result.print();
    return result;
  }
}

const useCaseVoid = new UseCaseVoid();
useCaseVoid.execute(); // 输出 void

const useCaseStr = new UseCaseString();
useCaseStr.execute(); // 输出 string

这种方式通过重载签名明确区分了两种场景:当你不需要传数据时直接调用Result.ok(),TypeScript会自动推断出返回的是Result<void>;当传入具体值时,会对应到正确的泛型类型,既满足了需求又保证了类型检查的严谨性。

内容的提问来源于stack exchange,提问作者A.L. Developer

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.23 12:18:09