最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - infer type of Higher order function return value when function parameter returns a promise - Stack Overflow

programmeradmin0浏览0评论

Basically I am trying to create a function defined like this:

function result<T>(cb: () => T): Result<T,Error> {
  try {
    return Ok(fn());
  } catch (error) {
    return Err(
      error instanceof Error ? (error as E) : (new Error(String(error)) as E)
    );
  }
}

it is a function that takes in another function that could throw e.g JSON.parse, and returns a rust-like result accordingly, so that when e.g result(() => JSON.parse(...)) fails it doesnt crash the program but it returns a Result with the error.

Now, this function works fine, but the problems arrive when i try to do async stuff.

i have this async variant:

async function resultrAsync<V, E extends Error>(
  fn: () => Promise<V>
): Promise<Result<V, E>> {
  try {
    return Ok(await fn());
  } catch (error) {
    return Err(
      error instanceof Error ? (error as E) : (new Error(String(error)) as E)
    );
  }
}

that should be used like this:

const result = await resultAsync(() => fetch(...))

and it works fine. But i want to overcomplicate things and join these 2 functions and do some generic magic, to handle cases where the callback functions is synchronous or not (JSON.parse vs fetch)

I tried with this:

type SyncOrAsync<V> = V | Promise<V>;

function resultr<V, E extends Error>(fn: () => V): Result<V, E>;
function resultr<V, E extends Error>(
 fn: () => Promise<V>
): Promise<Result<V, E>>;
function resultr<V, E extends Error>(
 fn: () => SyncOrAsync<V>
): SyncOrAsync<Result<V, E>> {
 try {
   const result = fn();
   if (result instanceof Promise) {
     return result
       .then(Ok)
       .catch(error =>
         Err(
           error instanceof Error
             ? (error as E)
             : (new Error(String(error)) as E)
         )
       ) as Promise<Result<V, E>>;
   } else {
     return Ok(result);
   }
 } catch (error) {
   return Err(
     error instanceof Error ? (error as E) : (new Error(String(error)) as E)
   );
 }
}

But when i use the async variant const res = result(() => fetch(url)) its return type is Result<Promise<Response>, Error> when it should be Promise<Result<V,Error>>

is this possible? i know its not probably a good idea but i want to get a grasp on generics.

与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论