Typescript - 是否可以使用泛型定义构造函数的接口?

时间:2017-04-24 00:52:23

标签: generics typescript

我基本上是想做这样的事情:

interface gen1<T> {
    constructor(param: T);
}
interface gen2<T> {
    constructor(param: gen1<any>);
}
class genImpl implements gen2<any> {
    constructor(param: gen1<any>) {

    }
}

但收到错误:

Class 'genImpl' incorrectly implements interface 'gen2<any>'.
  Types of property 'constructor' are incompatible.
    Type 'Function' is not assignable to type '(param: gen1<any>) => any'.
      Type 'Function' provides no match for the signature '(param: gen1<any>): any'.

2 个答案:

答案 0 :(得分:4)

接口中的构造函数签名无法在类中实现。这是设计的。来自documentation

  

使用类和接口时,请记住这一点   一个类有两种类型:静态类型和类型   实例方面。您可能会注意到,如果您创建一个界面   使用构造签名并尝试创建一个实现的类   这个界面你得到一个错误:

interface ClockConstructor {
    new (hour: number, minute: number);
}

class Clock implements ClockConstructor {
    currentTime: Date;
    constructor(h: number, m: number) { }
}
     

这是因为当一个类实现一个接口时,只有   检查类的实例端。由于构造函数位于   静态方面,它不包括在此检查中。

     

相反,您需要使用类的静态方面   直。在这个例子中,我们定义了两个接口ClockConstructor   用于实例方法的构造函数和ClockInterface。然后   为方便起见,我们定义了一个构造函数createClock   创建传递给它的类型的实例。

interface ClockConstructor {
    new (hour: number, minute: number): ClockInterface;
}
interface ClockInterface {
    tick();
}

function createClock(ctor: ClockConstructor, hour: number, minute: number): ClockInterface {
    return new ctor(hour, minute);
}

class DigitalClock implements ClockInterface {
    constructor(h: number, m: number) { }
    tick() {
        console.log("beep beep");
    }
}
class AnalogClock implements ClockInterface {
    constructor(h: number, m: number) { }
    tick() {
        console.log("tick tock");
    }
}

let digital = createClock(DigitalClock, 12, 17); let analog =
createClock(AnalogClock, 7, 32); 
     

因为createClock的第一个参数   它是ClockConstructor类型,在createClock(AnalogClock,7,32)中   检查AnalogClock是否具有正确的构造函数签名。

相关讨论:https://github.com/Microsoft/TypeScript/issues/8917

答案 1 :(得分:-1)

  

是否可以在构造函数中使用泛型?

  

但是收到错误

原因是gen<T>T

不同

修复

interface gen<T> {
    constructor(param: T);
}

class genImpl implements gen<any> {
    constructor(param: any) {

    }
}

即。在使用any的地方使用T。 (你错误地将T放到gen<any>any