Home > Enterprise >  How a generic void type can make an arg optional in typescript
How a generic void type can make an arg optional in typescript

Time:08-07

I'm trying to create a class that returns an instance that receives an argument with generic type, and sometimes this argument may not exist, I don't want to leave the possibly undefined, so I thought use void, but it throws.

The problem is I need to provide undefined value when generic type is void.


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> {
    
    // Here is the problem. I need to provide undefined value
    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(); // print void

const useCaseStr = new UseCaseString();

useCaseStr.execute(); // print string

Is it possible just use Result.ok() with no args?

a link is available on playground Playground Example Here

CodePudding user response:

In order to do that, you need to overload your constructor and ok methods:



class Result<A = void>{
  private readonly data: A | void;
  private constructor()
  private constructor(data: A)
  private constructor(data?: A) {
    this.data = data;
  }

  static ok(): Result<void>
  static ok<A>(data:A): Result<A>
  static ok<A>(data?: A) {
    return new Result(data);
  }
  print() {
    console.log(this.data ?? 'void');
  }
}

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

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

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


const useCaseVoid = new UseCaseVoid();

useCaseVoid.execute(); // print void

const useCaseStr = new UseCaseString();

useCaseStr.execute(); // print string


Playground

  • Related