繁体   English   中英

TypeScript 如何用不同的泛型返回类型包装函数?

[英]TypeScript how to wrap function with different generic return type?

如何创建一个可以将任何函数转换为安全函数的高阶函数? 通过拦截任何错误并将其作为结果返回?

type Errorneous<R> = 
  { is_error: true, message: string } | 
  { is_error: false, value: R }

function dangerous(msg: string): number { 
  throw new Error("not implemented") 
}
console.log(dangerous.to_safe()("Hi"))

代码有效,但 TypeScript 类型不正确,因为它不检查参数的正确性,并允许像dangerous.to_safe()() (不带参数)这样的无效调用。

操场

type Errorneous<R> = 
  { is_error: true, message: string } | 
  { is_error: false, value: R }

function dangerous(msg: string): number { 
  throw new Error("not implemented") 
}

declare global {
  interface Function {
    to_safe<Args extends ((...args: any[]) => any), R>(
      this: ((...args: Parameters<Args>) => R)
    ): ((...args: Parameters<Args>) => Errorneous<R>)
  }
}

Function.prototype.to_safe = function() {
  const self = this as any
  return function(...args: any[]) {
    try {
      return { is_error: false, value: self(...args) }
    } catch (e) {
      return { is_error: true, message: e.message }
    }
  }
}

console.log(dangerous.to_safe()("Hi"))

export const v = 0

聚苯乙烯

有办法,但不是很干净, 操场

declare global {
  interface Function {
    to_safe<A, R>(this: ((a: A) => R)): ((a: A) => Errorneous<R>)
    to_safe<A, B, R>(this: ((a: A, b: B) => R)): ((a: A, b: B) => Errorneous<R>)
    to_safe<A, B, C, R>(this: ((a: A, b: B, c: C) => R)): ((a: A, b: B, c: C) => Errorneous<R>)
  }
}

可变元组类型的帮助下,我们可以推断数组中的每个元素。 请参阅我的文章,您可以在其中找到如何推断它的详细说明。

type Errorneous<R> =
  { is_error: true, message: string } |
  { is_error: false, value: R }

function dangerous(msg: string): number {
  throw new Error("not implemented")
}

declare global {
  interface Function {
    to_safe<A extends any, Args extends A[], R>(this: ((...args: [...Args]) => R)): ((...args: [...Args]) => Errorneous<R>)
  }
}

Function.prototype.to_safe = function (this: Function) {
  const self = this
  return function <A extends any, Args extends A[]>(...args: [...Args]) {
    try {
      return { is_error: false, value: self(...args) }
    } catch (e) {
      return { is_error: true, message: e.message }
    }
  } as any
}

dangerous.to_safe()("Hi") // ok
dangerous.to_safe()() // error

export const v = 0

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM