具有通用方法的Typescript接口

时间:2019-11-28 12:17:56

标签: typescript

是否可以使用通用方法在Typescript中使用接口,以使我们知道T类型将扩展其他类型?

interface Abc {
  a: string;
  b: string;
  c: string;
}
interface Checkout {
  onComplete<T>(session: T): void
}
class StripeCheckout implements Checkout {
  onComplete<T extends Abc>(abc: T) {
    console.log(abc.a);
  }
}

onComplete方法无效

Property 'onComplete' in type 'StripeCheckout' is not assignable to the same property in base type 'Checkout'.
  Type '<T extends Abc>(session: T) => void' is not assignable to type '<T>(session: T) => void'.
    Types of parameters 'session' and 'session' are incompatible.
      Type 'T' is not assignable to type 'Abc'.(2416)

解决方案1(通用接口,它将迫使我们在类级别讲类型):

interface Abc {
  a: string;
  b: string;
  c: string;
}
interface Checkout<T> {
  onComplete(session: T): void
}
class StripeCheckout implements Checkout<Abc> {
  onComplete(session: Abc) {
    console.log(session);
  }
}

问题是,如果我将拥有更多具有不同类型的通用方法,它将看起来像Abc<T, U, V, Z>。我们可以使用多个接口来解决此问题,但是当我在类中定义方法时,我想告诉Typescript有关通用方法类型的信息。

解决方案2(“通用”与任何解决方案):

interface Abc {
  a: string;
  b: string;
  c: string;
}
interface Checkout {
  onComplete(session: any): void
}
class StripeCheckout implements Checkout {
  onComplete(session: Abc) {
    console.log(session);
  }
}

用法示例:

const checkout = new StripeCheckout();
checkout.onComplete({a: '1', b: '2', c: '3'})

1 个答案:

答案 0 :(得分:1)

TypeScript和许多其他语言将不允许您执行此操作,我建议使用第一种解决方案。

interface Abc {
    a: string;
    b: string;
    c: string;
}
interface Default {
    a: number;
}
interface Checkout<T, A=Default> {
    onComplete(session: T): void;
    otherFunction(input: A) : void;
}
class StripeCheckout implements Checkout<Abc> {
    otherFunction(input: Default) {
        throw new Error("Method not implemented.");
    }
    onComplete(session: Abc) {
        console.log(session);
    }
}

为什么?因为这样您可以在Checkout界面上设置泛型的限制,从而为您提供更多控制权。您的界面应定义合同,而不是实现合同的类。