在接口中通过超类限制类型

时间:2017-08-24 05:19:41

标签: typescript inheritance interface typeof

我想创建一个接口,它定义了一组键值值,其值限制为classWhichExtendsSpecificSuperClass。

例如,这个界面:

interface MyInterface {
     key: typeof SuperClass
}

和这个基类:

class BaseClass extends SuperClass {...}

以这种方式应用:

function myFunction(arg: MyInterface) {...};

myFunction({
   key: BaseClass
});

上面的代码告诉我,typeof BaseClass不能分配给类型的SuperClass。

现在我知道我正在做的事情是不正确的,但是有可能以其他方式吗?我想确保" key"的唯一允许值。是扩展SuperClass的类型类型吗?

如果我正在处理函数,我可以使用泛型,但据我所知,没有办法在object属性上表达泛型。

任何帮助都会很棒!

1 个答案:

答案 0 :(得分:1)

如果所有扩展SuperClass的类都具有兼容的构造函数参数,那么您的代码应该没有错误。例如:

class SuperClass {
  superValue: string;
}
interface MyInterface {
     key: typeof SuperClass
}
class BaseClass extends SuperClass {
  baseValue: string;
}
function myFunction(arg: MyInterface) { };
myFunction({
   key: BaseClass // no error
});

这里没有问题,因为BaseClassSuperClass都可以用零参数构造。但是如果你改变BaseClass的构造函数:

class BaseClass extends SuperClass {
  baseValue: string;
  constructor(someArgument: string) {
    super();
  }
}

当您致电myFunction()时,您会收到错误提示:

Argument of type '{ key: typeof BaseClass; }' is not assignable to parameter of type 'MyInterface'.
  Types of property 'key' are incompatible.
    Type 'typeof BaseClass' is not assignable to type 'typeof SuperClass'.

现在,根据您对MyInterface的要求,该错误可能很重要。您是否打算使用key MyInterface的{​​{1}}属性并使用它来构造SuperClass的某个子类的实例?例如:

declare let myInterface: MyInterface;
let someInstance = new myInterface.key();

如果是这样,那么你需要确保类构造函数接受正确的参数数量和类型,并且该错误对您有帮助。它告诉您更改BaseClass构造函数以与SuperClass的构造函数兼容。例如,如果我们将someArgument设为可选:

class BaseClass extends SuperClass {
  baseValue: string;
  constructor(someArgument?: string) {
    super();
  }
}

然后错误就消失了,因为new SubClass()现在可以不使用任何参数。

如果打算使用MyInterface来构造实例,并且关心构造函数的参数的数量和类型拿,你只是希望它出于某种原因持有一些类构造函数...然后你可以这样做:

type Constructor<T> = {
  new(...args: any[]): T; // any number and type of arguments
}
interface MyInterface {
     key: Constructor<SuperClass>
}

即使构造函数签名不兼容,现在myFunction()也能正常工作。那是因为你真的不想把自己限制在typeof SuperClass;您想接受创建SuperClass的任何构造函数,这就是Constructor<SuperClass>的含义。所以错误消失了,你很高兴。

希望这两种解决方案中的一种能为您服务。祝你好运!