首页 > 解决方案 > TypeScript:如何委托接口方法

问题描述

我有一个来自 3rd 方库的这样的界面:

MyInterface{
    foo(arg: string): Promise<any>;
    foo(arg: string, ...params: any[]): Promise<any>;

    foo<T>(arg: string): Promise<T>;
    foo<T>(arg: string, ...params: any[]): Promise<T>;

    bar(arg: string, callback?: (err: Error, row: any) => void): Promise<number>;
    bar(arg: string, ...params: any[]): Promise<number>;
}

我想将接口方法委托给相同类型的实现,如下所示:

MyClass implements MyInterface {

  private impl:MyInterface = ...
  
  foo(..) //how to do it right ??


  // TS2393: Duplicate function implementation.
  bar(arg: string, callback?: (err: Error, row: any) => void): Promise<number>{
     return impl.bar(sql,callback);
  }

  // TS2393: Duplicate function implementation.
  bar(arg, ...params: any[]): Promise<number>{
      return impl.bar(arg,params);
  }
}

我不知道如何正确实现委托,所以impl调用了正确的方法。

既没有TypeScript 函数重载 ,也没有办法在 TypeScript 中进行方法重载? 正在帮助我做出正确的授权。

标签: typescriptproxy-pattern

解决方案


不是最好的解决方案,但仍然有一些解决方法:

interface MyInterface {
   foo(arg: string): string
   foo(arg: number): number
}

class Foo implements MyInterface {
   foo(arg: string): string;
   foo(arg: number): number;
   // foo(arg: number): string; -> error, if you uncomment this line, please comment line above

   foo(arg: string | number) {
      if (typeof arg === 'string') {
         return arg
      }
      return 12 as number
   }
}

const result = new Foo().foo(2)

坏消息:你应该写所有的重载。AFAIK,不可能用重载映射接口

好消息:如果您提供与实现的接口不兼容的函数重载,TS 会抱怨。

更新

还有一种替代方法。

您可能不需要Foo通过扩展类MyInterface

interface MyInterface {
   foo(arg: string): string
   foo(arg: number): number
}

class Foo {
   foo(arg: string): string;
   foo(arg: number): number;
   foo(arg: string | number) {
      if (typeof arg === 'string') {
         return arg
      }
      return 12 as number
   }
}

// sorry, I can't find the link to the author of this type utility
type DeepEqual<X, Y> =
   (<T>() => T extends X ? 1 : 2) extends
   (<T>() => T extends Y ? 1 : 2) ? true : false;

/**
 * Here you can just check if types are deep equal or not
 * Try to change overloadings for `foo` method and you
 * will see that Result type will be falsy
 */
type L = Deep<Foo, MyInterface>

推荐阅读