Home > Software design >  Enforce type check with optional argument in TypeScript
Enforce type check with optional argument in TypeScript

Time:01-19

Following this article, I'm trying to mimic Rust's Result<T,E> type in TypeScript, this is the code:

type Result<T, E> =
  | { ok: true; data: T }
  | { ok: false; error: E };

const Ok = <T>(data: T): Result<T, never> => {
  return { ok: true, data };
};

const Err = <E>(error: E): Result<never, E> => {
  return { ok: false, error };
};

I want to make it a bit better, so that the Ok() argument could be optional if the T type is undefined, but if I make it optional, all the other types do not enforce argument to be present.

E.g. If I change data: T argument of Ok() to be data?: T, I can use Ok() with no value.

function testFunc(isOk: boolean): Result<undefined, Error> {
  if (isOk) {
    return Ok();
  }

  return Err(new Error("my error"));
}

But I can't enforce other type:

function testFunc(isOk: boolean): Result<number, Error> {
  if (isOk) {
    // --- Gives me an error (string is not assignable to number)
    return Ok('hi');
    // --- Doesn't give me an error, but I need it
    return Ok();
  }

  return Err(new Error("my error"));
}

Is it even possible to do something like this, considering I want to only use these two functions Ok and Err ?

CodePudding user response:

You can try using function overloading:

function Ok<T>(): Result<T | undefined, never>;
function Ok<T>(data: T): Result<T, never>;
function Ok<T>(data?: T): Result<T | undefined, never> {
  return { ok: true, data };
}
  • Related