0

我正在通过嵌入到第三方软件 API 的 JS 创建一个 TS 包装器,该 API 不受我管理。我想在类型和接口中捕获尽可能多的行为,因为无类型的 vanilla JS 在我的情况下很难让它工作。

所以,更具体地说:

我有外部对象,并且我有一个接口,它声明了它具有的功能

declare var foo: object  
interface FooContract {
  function doFooStuff: (fooParam: string) => BlaError | Success
  function doBarStuff: (barParam: string) => BlaError | Success
}

我想检查一下:

  1. 给定对象foo具有字段doFooStuffdoBarStuff
  2. 这些字段是函数。
  3. 这些函数采用我描述的参数,如果不返回有意义的错误消息,至少检查 arity。
  4. 这些函数返回返回类型中描述的数据,如果没有返回有意义的错误消息。

所以我实际上确实理解 3) 和 4) 几乎是运行时检查,应该通过测试来验证,但无论如何。

有时 API 会抛出一些错误,我想以某种方式描述和指示将返回哪个错误。错误主要是字符串和 POJO,我想为它们分配类型(最好是名义上的,以任何数量的轮子重新发明和肮脏的黑客为代价)。

到目前为止,我来到:

declare var foo: object  
interface FooContract {
  function doFooStuff: (fooParam: string) => BlaError | Success
  function doBarStuff: (barParam: string) => BlaError | Success
}

function isFooContract(x: object): x is FooContract {
  const r = x as FooContract
  return r.doFooStuff !== undefined && (typeof r.doFooStuff) == "function" &&
         r.doBarStuff && (typeof r.doFooStuff) == "function"
}

class FooOps {
  private fooInternal: FooContract
  constructor (_inner: object) {
    if(isFooContract(_inner))  
      this.fooInternal = _inner
    else 
      throw new EverythingIsBrokenException(_inner, "foo object not satisfies listed asserts")
  }
  function doFooStuff(fooParam: string): BlaError | Success {
    const ret = this.fooInternal(fooParam) 
    if(isBlaError(ret)) 
      return ret
    else if (isSuccess)
      return ret
    else 
      throw new EverythingIsBrokenException(ret, "Returned value of Foo.doFooStuff is not error nor success but something unexpected")
  }
}

所以根本没有 3),我需要手写大量的样板。是否有某种代码生成/编译器宏扩展/编译时反射工具来检查字段是否存在?

4

0 回答 0