抽象接口不能用作数组中的类型 - 缺少 属性

Abstract interface cannot be used as type in array - missing property

我有这个界面:

export interface SceEvent {
  // ...
}

export interface SceMain {

  onComplete: () => void;

  onNextEvent: (ev: SceEvent) => void;

  getRawGeneratedCode: () => string;

  getStyledGeneratedCode: () => string;

}

我在几个文件中实现了这个接口,如下所示:

import {SceEvent, SceMain} from "../../interfaces";

export class CodeGenerator implements SceMain {

  private rawCode = '';
  private styledCode = '';
  public static pluginName = 'java-junit';

  constructor(){

  }

  getRawGeneratedCode() {
    return this.rawCode;
  }


  getStyledGeneratedCode() {
    return this.styledCode;
  }

  onComplete(){

  }


  onNextEvent(ev: SceEvent) {

  }

}

然后在另一个文件中,我导出所有这些实现:

import {SceMain} from "./interfaces";

// generators
import * as javajunit from './values/java-junit';
import * as javatestng from './values/java-test-ng';
import * as nodejsmocha from './values/nodejs-mocha';
import * as nodejssuman from './values/nodejs-suman';


export const plugins : Array<SceMain>= [

  javajunit.CodeGenerator,
  javatestng.CodeGenerator,
  nodejsmocha.CodeGenerator,
  nodejssuman.CodeGenerator

];

但我收到此错误:

Property "onComplete" is missing in typeof CodeGenerator

我不明白,因为我所有的 CodeGenerator 类 都实现了这个方法。

这是一张图片的错误...

有人知道这里发生了什么吗?

因为plugins是构造函数数组,不是实例数组,那么类型需要改变:

//原创

plugins: Array<SceMain>

// 改进

plugins: Array<new() => SceMain>

感谢@jcalz 的回答

plugins常量是SceMain构造函数的数组,而不是SceMain实例[=的数组50=]。 SceMain 的实例具有类似于 onComplete() 的方法,但构造函数没有(除非它碰巧具有具有正确签名的静态方法)。编译器警告您数组的元素不是 SceMain.

的实例

假设您实际上打算创建一个构造函数数组(正如您在评论中提到的),您应该键入 plugins,例如:

export const plugins : Array<new() => SceMain>= [    
  javajunit.CodeGenerator,
  javatestng.CodeGenerator,
  nodejsmocha.CodeGenerator,
  nodejssuman.CodeGenerator    
];

类型 new() => SceMain 是产生 SceMain 实例的无参数构造函数的类型。 (如果您的构造函数采用参数,则应修改类型。)


你的困惑很可能源于这样一个事实,即在 TypeScript 中,当你声明一个名为 classclass Foo {} 时,它会创建一个名为 typeFoo,对应class的instances,还有一个名为Foovalue,也就是构造函数的 class。值 Foo 不是 Foo 类型。但是,它的类型为 new ()=>Foo。您可以使用 typeof 类型运算符获得更具体类型的 class 构造函数(包括静态方法): typeof FooFoo 构造函数的类型。您可以在 TypeScript Handbook 中阅读更多相关信息。

类型表达式和值表达式之间的区别很难解释,尤其是因为 TypeScript 倾向于在两种类型的表达式中使用相同的关键字来表示不同的(并且可能只是略微相关的)事物:

class Foo {}

const foo: Foo = new Foo();  
// the first Foo is the instance type, 
// the second Foo is the constructor value

const fooConstructor: typeof Foo = Foo; 
// the first Foo is the constructor value
// typeof is a type query acting on it at design time
// the second Foo is the constructor value

const theWordFunction: string = typeof Foo;
// Foo is the constructor value
// typeof is the JavaScript typeof operator acting on it at runtime
// It will just be "function"

我不知道这是否解决了问题还是让事情变得更糟。无论如何,祝你好运!